<s> from __future__ import print_function , division <EOL> from collections import defaultdict <EOL> from functools import cmp_to_key <EOL> import operator <EOL> from . sympify import sympify <EOL> from . basic import Basic <EOL> from . singleton import S <EOL> from . operations import AssocOp <EOL> from . cache import cacheit <EOL> from . logic import fuzzy_not , _fuzzy_group <EOL> from . compatibility import reduce , range <EOL> from . expr import Expr <EOL> class NC_Marker : <EOL> is_Order = False <EOL> is_Mul = False <EOL> is_Number = False <EOL> is_Poly = False <EOL> is_commutative = False <EOL> _args_sortkey = cmp_to_key ( Basic . compare ) <EOL> def _mulsort ( args ) : <EOL> args . sort ( key = _args_sortkey ) <EOL> def _unevaluated_Mul ( * args ) : <EOL> """<STR_LIT>""" <EOL> args = list ( args ) <EOL> newargs = [ ] <EOL> ncargs = [ ] <EOL> co = S . One <EOL> while args : <EOL> a = args . pop ( ) <EOL> if a . is_Mul : <EOL> c , nc = a . args_cnc ( ) <EOL> args . extend ( c ) <EOL> if nc : <EOL> ncargs . append ( Mul . _from_args ( nc ) ) <EOL> elif a . is_Number : <EOL> co *= a <EOL> else : <EOL> newargs . append ( a ) <EOL> _mulsort ( newargs ) <EOL> if co is not S . One : <EOL> newargs . insert ( <NUM_LIT:0> , co ) <EOL> if ncargs : <EOL> newargs . append ( Mul . _from_args ( ncargs ) ) <EOL> return Mul . _from_args ( newargs ) <EOL> class Mul ( Expr , AssocOp ) : <EOL> __slots__ = [ ] <EOL> is_Mul = True <EOL> @ classmethod <EOL> def flatten ( cls , seq ) : <EOL> """<STR_LIT>""" <EOL> from sympy . calculus . util import AccumBounds <EOL> rv = None <EOL> if len ( seq ) == <NUM_LIT:2> : <EOL> a , b = seq <EOL> if b . is_Rational : <EOL> a , b = b , a <EOL> assert not a is S . One <EOL> if not a . is_zero and a . is_Rational : <EOL> r , b = b . as_coeff_Mul ( ) <EOL> if b . is_Add : <EOL> if r is not S . One : <EOL> rv = [ cls ( a * r , b , evaluate = False ) ] , [ ] , None <EOL> elif b . is_commutative : <EOL> if a is S . One : <EOL> rv = [ b ] , [ ] , None <EOL> else : <EOL> r , b = b . as_coeff_Add ( ) <EOL> bargs = [ _keep_coeff ( a , bi ) for bi in Add . make_args ( b ) ] <EOL> _addsort ( bargs ) <EOL> ar = a * r <EOL> if ar : <EOL> bargs . insert ( <NUM_LIT:0> , ar ) <EOL> bargs = [ Add . _from_args ( bargs ) ] <EOL> rv = bargs , [ ] , None <EOL> if rv : <EOL> return rv <EOL> c_part = [ ] <EOL> nc_part = [ ] <EOL> nc_seq = [ ] <EOL> coeff = S . One <EOL> c_powers = [ ] <EOL> num_exp = [ ] <EOL> neg1e = S . Zero <EOL> pnum_rat = { } <EOL> order_symbols = None <EOL> for o in seq : <EOL> if o . is_Order : <EOL> o , order_symbols = o . as_expr_variables ( order_symbols ) <EOL> if o . is_Mul : <EOL> if o . is_commutative : <EOL> seq . extend ( o . args ) <EOL> else : <EOL> for q in o . args : <EOL> if q . is_commutative : <EOL> seq . append ( q ) <EOL> else : <EOL> nc_seq . append ( q ) <EOL> seq . append ( NC_Marker ) <EOL> continue <EOL> elif o . is_Number : <EOL> if o is S . NaN or coeff is S . ComplexInfinity and o is S . Zero : <EOL> return [ S . NaN ] , [ ] , None <EOL> elif coeff . is_Number : <EOL> coeff *= o <EOL> if coeff is S . NaN : <EOL> return [ S . NaN ] , [ ] , None <EOL> continue <EOL> elif isinstance ( o , AccumBounds ) : <EOL> coeff = o . __mul__ ( coeff ) <EOL> continue <EOL> elif o is S . ComplexInfinity : <EOL> if not coeff : <EOL> return [ S . NaN ] , [ ] , None <EOL> if coeff is S . ComplexInfinity : <EOL> return [ S . ComplexInfinity ] , [ ] , None <EOL> coeff = S . ComplexInfinity <EOL> continue <EOL> elif o is S . ImaginaryUnit : <EOL> neg1e += S . Half <EOL> continue <EOL> elif o . is_commutative : <EOL> b , e = o . as_base_exp ( ) <EOL> if o . is_Pow : <EOL> if b . is_Number : <EOL> if e . is_Rational : <EOL> if e . is_Integer : <EOL> coeff *= Pow ( b , e ) <EOL> continue <EOL> elif e . is_negative : <EOL> seq . append ( Pow ( b , e ) ) <EOL> continue <EOL> elif b . is_negative : <EOL> neg1e += e <EOL> b = - b <EOL> if b is not S . One : <EOL> pnum_rat . setdefault ( b , [ ] ) . append ( e ) <EOL> continue <EOL> elif b . is_positive or e . is_integer : <EOL> num_exp . append ( ( b , e ) ) <EOL> continue <EOL> elif b is S . ImaginaryUnit and e . is_Rational : <EOL> neg1e += e / <NUM_LIT:2> <EOL> continue <EOL> c_powers . append ( ( b , e ) ) <EOL> else : <EOL> if o is not NC_Marker : <EOL> nc_seq . append ( o ) <EOL> while nc_seq : <EOL> o = nc_seq . pop ( <NUM_LIT:0> ) <EOL> if not nc_part : <EOL> nc_part . append ( o ) <EOL> continue <EOL> o1 = nc_part . pop ( ) <EOL> b1 , e1 = o1 . as_base_exp ( ) <EOL> b2 , e2 = o . as_base_exp ( ) <EOL> new_exp = e1 + e2 <EOL> if b1 == b2 and ( not new_exp . is_Add ) : <EOL> o12 = b1 ** new_exp <EOL> if o12 . is_commutative : <EOL> seq . append ( o12 ) <EOL> continue <EOL> else : <EOL> nc_seq . insert ( <NUM_LIT:0> , o12 ) <EOL> else : <EOL> nc_part . append ( o1 ) <EOL> nc_part . append ( o ) <EOL> def _gather ( c_powers ) : <EOL> common_b = { } <EOL> for b , e in c_powers : <EOL> co = e . as_coeff_Mul ( ) <EOL> common_b . setdefault ( b , { } ) . setdefault ( <EOL> co [ <NUM_LIT:1> ] , [ ] ) . append ( co [ <NUM_LIT:0> ] ) <EOL> for b , d in common_b . items ( ) : <EOL> for di , li in d . items ( ) : <EOL> d [ di ] = Add ( * li ) <EOL> new_c_powers = [ ] <EOL> for b , e in common_b . items ( ) : <EOL> new_c_powers . extend ( [ ( b , c * t ) for t , c in e . items ( ) ] ) <EOL> return new_c_powers <EOL> c_powers = _gather ( c_powers ) <EOL> num_exp = _gather ( num_exp ) <EOL> for i in range ( <NUM_LIT:2> ) : <EOL> new_c_powers = [ ] <EOL> changed = False <EOL> for b , e in c_powers : <EOL> if e . is_zero : <EOL> continue <EOL> if e is S . One : <EOL> if b . is_Number : <EOL> coeff *= b <EOL> continue <EOL> p = b <EOL> if e is not S . One : <EOL> p = Pow ( b , e ) <EOL> if p . is_Pow and not b . is_Pow : <EOL> bi = b <EOL> b , e = p . as_base_exp ( ) <EOL> if b != bi : <EOL> changed = True <EOL> c_part . append ( p ) <EOL> new_c_powers . append ( ( b , e ) ) <EOL> if changed and len ( set ( <EOL> b for b , e in new_c_powers ) ) != len ( new_c_powers ) : <EOL> c_part = [ ] <EOL> c_powers = _gather ( new_c_powers ) <EOL> else : <EOL> break <EOL> inv_exp_dict = { } <EOL> for b , e in num_exp : <EOL> inv_exp_dict . setdefault ( e , [ ] ) . append ( b ) <EOL> for e , b in inv_exp_dict . items ( ) : <EOL> inv_exp_dict [ e ] = cls ( * b ) <EOL> c_part . extend ( [ Pow ( b , e ) for e , b in inv_exp_dict . items ( ) if e ] ) <EOL> comb_e = { } <EOL> for b , e in pnum_rat . items ( ) : <EOL> comb_e . setdefault ( Add ( * e ) , [ ] ) . append ( b ) <EOL> del pnum_rat <EOL> num_rat = [ ] <EOL> for e , b in comb_e . items ( ) : <EOL> b = cls ( * b ) <EOL> if e . q == <NUM_LIT:1> : <EOL> coeff *= Pow ( b , e ) <EOL> continue <EOL> if e . p > e . q : <EOL> e_i , ep = divmod ( e . p , e . q ) <EOL> coeff *= Pow ( b , e_i ) <EOL> e = Rational ( ep , e . q ) <EOL> num_rat . append ( ( b , e ) ) <EOL> del comb_e <EOL> pnew = defaultdict ( list ) <EOL> i = <NUM_LIT:0> <EOL> while i < len ( num_rat ) : <EOL> bi , ei = num_rat [ i ] <EOL> grow = [ ] <EOL> for j in range ( i + <NUM_LIT:1> , len ( num_rat ) ) : <EOL> bj , ej = num_rat [ j ] <EOL> g = bi . gcd ( bj ) <EOL> if g is not S . One : <EOL> e = ei + ej <EOL> if e . q == <NUM_LIT:1> : <EOL> coeff *= Pow ( g , e ) <EOL> else : <EOL> if e . p > e . q : <EOL> e_i , ep = divmod ( e . p , e . q ) <EOL> coeff *= Pow ( g , e_i ) <EOL> e = Rational ( ep , e . q ) <EOL> grow . append ( ( g , e ) ) <EOL> num_rat [ j ] = ( bj / g , ej ) <EOL> bi = bi / g <EOL> if bi is S . One : <EOL> break <EOL> if bi is not S . One : <EOL> obj = Pow ( bi , ei ) <EOL> if obj . is_Number : <EOL> coeff *= obj <EOL> else : <EOL> for obj in Mul . make_args ( obj ) : <EOL> if obj . is_Number : <EOL> coeff *= obj <EOL> else : <EOL> assert obj . is_Pow <EOL> bi , ei = obj . args <EOL> pnew [ ei ] . append ( bi ) <EOL> num_rat . extend ( grow ) <EOL> i += <NUM_LIT:1> <EOL> for e , b in pnew . items ( ) : <EOL> pnew [ e ] = cls ( * b ) <EOL> if neg1e : <EOL> p , q = neg1e . as_numer_denom ( ) <EOL> n , p = divmod ( p , q ) <EOL> if n % <NUM_LIT:2> : <EOL> coeff = - coeff <EOL> if q == <NUM_LIT:2> : <EOL> c_part . append ( S . ImaginaryUnit ) <EOL> elif p : <EOL> neg1e = Rational ( p , q ) <EOL> for e , b in pnew . items ( ) : <EOL> if e == neg1e and b . is_positive : <EOL> pnew [ e ] = - b <EOL> break <EOL> else : <EOL> c_part . append ( Pow ( S . NegativeOne , neg1e , evaluate = False ) ) <EOL> c_part . extend ( [ Pow ( b , e ) for e , b in pnew . items ( ) ] ) <EOL> if ( coeff is S . Infinity ) or ( coeff is S . NegativeInfinity ) : <EOL> def _handle_for_oo ( c_part , coeff_sign ) : <EOL> new_c_part = [ ] <EOL> for t in c_part : <EOL> if t . is_positive : <EOL> continue <EOL> if t . is_negative : <EOL> coeff_sign *= - <NUM_LIT:1> <EOL> continue <EOL> new_c_part . append ( t ) <EOL> return new_c_part , coeff_sign <EOL> c_part , coeff_sign = _handle_for_oo ( c_part , <NUM_LIT:1> ) <EOL> nc_part , coeff_sign = _handle_for_oo ( nc_part , coeff_sign ) <EOL> coeff *= coeff_sign <EOL> if coeff is S . ComplexInfinity : <EOL> c_part = [ c for c in c_part if not ( fuzzy_not ( c . is_zero ) and <EOL> c . is_real is not None ) ] <EOL> nc_part = [ c for c in nc_part if not ( fuzzy_not ( c . is_zero ) and <EOL> c . is_real is not None ) ] <EOL> elif coeff is S . Zero : <EOL> if any ( c . is_finite == False for c in c_part ) : <EOL> return [ S . NaN ] , [ ] , order_symbols <EOL> return [ coeff ] , [ ] , order_symbols <EOL> _new = [ ] <EOL> for i in c_part : <EOL> if i . is_Number : <EOL> coeff *= i <EOL> else : <EOL> _new . append ( i ) <EOL> c_part = _new <EOL> _mulsort ( c_part ) <EOL> if coeff is not S . One : <EOL> c_part . insert ( <NUM_LIT:0> , coeff ) <EOL> if ( not nc_part and len ( c_part ) == <NUM_LIT:2> and c_part [ <NUM_LIT:0> ] . is_Number and <EOL> c_part [ <NUM_LIT:1> ] . is_Add ) : <EOL> coeff = c_part [ <NUM_LIT:0> ] <EOL> c_part = [ Add ( * [ coeff * f for f in c_part [ <NUM_LIT:1> ] . args ] ) ] <EOL> return c_part , nc_part , order_symbols <EOL> def _eval_power ( b , e ) : <EOL> cargs , nc = b . args_cnc ( split_1 = False ) <EOL> if e . is_Integer : <EOL> return Mul ( * [ Pow ( b , e , evaluate = False ) for b in cargs ] ) * Pow ( Mul . _from_args ( nc ) , e , evaluate = False ) <EOL> p = Pow ( b , e , evaluate = False ) <EOL> if e . is_Rational or e . is_Float : <EOL> return p . _eval_expand_power_base ( ) <EOL> return p <EOL> @ classmethod <EOL> def class_key ( cls ) : <EOL> return <NUM_LIT:3> , <NUM_LIT:0> , cls . __name__ <EOL> def _eval_evalf ( self , prec ) : <EOL> c , m = self . as_coeff_Mul ( ) <EOL> if c is S . NegativeOne : <EOL> if m . is_Mul : <EOL> rv = - AssocOp . _eval_evalf ( m , prec ) <EOL> else : <EOL> mnew = m . _eval_evalf ( prec ) <EOL> if mnew is not None : <EOL> m = mnew <EOL> rv = - m <EOL> else : <EOL> rv = AssocOp . _eval_evalf ( self , prec ) <EOL> if rv . is_number : <EOL> return rv . expand ( ) <EOL> return rv <EOL> @ cacheit <EOL> def as_two_terms ( self ) : <EOL> """<STR_LIT>""" <EOL> args = self . args <EOL> if len ( args ) == <NUM_LIT:1> : <EOL> return S . One , self <EOL> elif len ( args ) == <NUM_LIT:2> : <EOL> return args <EOL> else : <EOL> return args [ <NUM_LIT:0> ] , self . _new_rawargs ( * args [ <NUM_LIT:1> : ] ) <EOL> @ cacheit <EOL> def as_coeff_mul ( self , * deps , ** kwargs ) : <EOL> rational = kwargs . pop ( '<STR_LIT>' , True ) <EOL> if deps : <EOL> l1 = [ ] <EOL> l2 = [ ] <EOL> for f in self . args : <EOL> if f . has ( * deps ) : <EOL> l2 . append ( f ) <EOL> else : <EOL> l1 . append ( f ) <EOL> return self . _new_rawargs ( * l1 ) , tuple ( l2 ) <EOL> args = self . args <EOL> if args [ <NUM_LIT:0> ] . is_Number : <EOL> if not rational or args [ <NUM_LIT:0> ] . is_Rational : <EOL> return args [ <NUM_LIT:0> ] , args [ <NUM_LIT:1> : ] <EOL> elif args [ <NUM_LIT:0> ] . is_negative : <EOL> return S . NegativeOne , ( - args [ <NUM_LIT:0> ] , ) + args [ <NUM_LIT:1> : ] <EOL> return S . One , args <EOL> def as_coeff_Mul ( self , rational = False ) : <EOL> """<STR_LIT>""" <EOL> coeff , args = self . args [ <NUM_LIT:0> ] , self . args [ <NUM_LIT:1> : ] <EOL> if coeff . is_Number : <EOL> if not rational or coeff . is_Rational : <EOL> if len ( args ) == <NUM_LIT:1> : <EOL> return coeff , args [ <NUM_LIT:0> ] <EOL> else : <EOL> return coeff , self . _new_rawargs ( * args ) <EOL> elif coeff . is_negative : <EOL> return S . NegativeOne , self . _new_rawargs ( * ( ( - coeff , ) + args ) ) <EOL> return S . One , self <EOL> def as_real_imag ( self , deep = True , ** hints ) : <EOL> from sympy import Abs , expand_mul , im , re <EOL> other = [ ] <EOL> coeffr = [ ] <EOL> coeffi = [ ] <EOL> addterms = S . One <EOL> for a in self . args : <EOL> if a . is_real : <EOL> coeffr . append ( a ) <EOL> elif a . is_imaginary : <EOL> coeffi . append ( a ) <EOL> elif a . is_commutative : <EOL> for i , x in enumerate ( other ) : <EOL> if x == a . conjugate ( ) : <EOL> coeffr . append ( Abs ( x ) ** <NUM_LIT:2> ) <EOL> del other [ i ] <EOL> break <EOL> else : <EOL> if a . is_Add : <EOL> addterms *= a <EOL> else : <EOL> other . append ( a ) <EOL> else : <EOL> other . append ( a ) <EOL> m = self . func ( * other ) <EOL> if hints . get ( '<STR_LIT:ignore>' ) == m : <EOL> return <EOL> if len ( coeffi ) % <NUM_LIT:2> : <EOL> imco = im ( coeffi . pop ( <NUM_LIT:0> ) ) <EOL> else : <EOL> imco = S . Zero <EOL> reco = self . func ( * ( coeffr + coeffi ) ) <EOL> r , i = ( reco * re ( m ) , reco * im ( m ) ) <EOL> if addterms == <NUM_LIT:1> : <EOL> if m == <NUM_LIT:1> : <EOL> if imco is S . Zero : <EOL> return ( reco , S . Zero ) <EOL> else : <EOL> return ( S . Zero , reco * imco ) <EOL> if imco is S . Zero : <EOL> return ( r , i ) <EOL> return ( - imco * i , imco * r ) <EOL> addre , addim = expand_mul ( addterms , deep = False ) . as_real_imag ( ) <EOL> if imco is S . Zero : <EOL> return ( r * addre - i * addim , i * addre + r * addim ) <EOL> else : <EOL> r , i = - imco * i , imco * r <EOL> return ( r * addre - i * addim , r * addim + i * addre ) <EOL> @ staticmethod <EOL> def _expandsums ( sums ) : <EOL> """<STR_LIT>""" <EOL> L = len ( sums ) <EOL> if L == <NUM_LIT:1> : <EOL> return sums [ <NUM_LIT:0> ] . args <EOL> terms = [ ] <EOL> left = Mul . _expandsums ( sums [ : L // <NUM_LIT:2> ] ) <EOL> right = Mul . _expandsums ( sums [ L // <NUM_LIT:2> : ] ) <EOL> terms = [ Mul ( a , b ) for a in left for b in right ] <EOL> added = Add ( * terms ) <EOL> return Add . make_args ( added ) <EOL> def _eval_expand_mul ( self , ** hints ) : <EOL> from sympy import fraction <EOL> expr = self <EOL> n , d = fraction ( expr ) <EOL> if d . is_Mul : <EOL> n , d = [ i . _eval_expand_mul ( ** hints ) if i . is_Mul else i <EOL> for i in ( n , d ) ] <EOL> expr = n / d <EOL> if not expr . is_Mul : <EOL> return expr <EOL> plain , sums , rewrite = [ ] , [ ] , False <EOL> for factor in expr . args : <EOL> if factor . is_Add : <EOL> sums . append ( factor ) <EOL> rewrite = True <EOL> else : <EOL> if factor . is_commutative : <EOL> plain . append ( factor ) <EOL> else : <EOL> sums . append ( Basic ( factor ) ) <EOL> if not rewrite : <EOL> return expr <EOL> else : <EOL> plain = self . func ( * plain ) <EOL> if sums : <EOL> terms = self . func . _expandsums ( sums ) <EOL> args = [ ] <EOL> for term in terms : <EOL> t = self . func ( plain , term ) <EOL> if t . is_Mul and any ( a . is_Add for a in t . args ) : <EOL> t = t . _eval_expand_mul ( ) <EOL> args . append ( t ) <EOL> return Add ( * args ) <EOL> else : <EOL> return plain <EOL> @ cacheit <EOL> def _eval_derivative ( self , s ) : <EOL> args = list ( self . args ) <EOL> terms = [ ] <EOL> for i in range ( len ( args ) ) : <EOL> d = args [ i ] . diff ( s ) <EOL> if d : <EOL> terms . append ( self . func ( * ( args [ : i ] + [ d ] + args [ i + <NUM_LIT:1> : ] ) ) ) <EOL> return Add ( * terms ) <EOL> def _eval_difference_delta ( self , n , step ) : <EOL> from sympy . series . limitseq import difference_delta as dd <EOL> arg0 = self . args [ <NUM_LIT:0> ] <EOL> rest = Mul ( * self . args [ <NUM_LIT:1> : ] ) <EOL> return ( arg0 . subs ( n , n + step ) * dd ( rest , n , step ) + dd ( arg0 , n , step ) * <EOL> rest ) <EOL> def _matches_simple ( self , expr , repl_dict ) : <EOL> coeff , terms = self . as_coeff_Mul ( ) <EOL> terms = Mul . make_args ( terms ) <EOL> if len ( terms ) == <NUM_LIT:1> : <EOL> newexpr = self . __class__ . _combine_inverse ( expr , coeff ) <EOL> return terms [ <NUM_LIT:0> ] . matches ( newexpr , repl_dict ) <EOL> return <EOL> def matches ( self , expr , repl_dict = { } , old = False ) : <EOL> expr = sympify ( expr ) <EOL> if self . is_commutative and expr . is_commutative : <EOL> return AssocOp . _matches_commutative ( self , expr , repl_dict , old ) <EOL> elif self . is_commutative is not expr . is_commutative : <EOL> return None <EOL> c1 , nc1 = self . args_cnc ( ) <EOL> c2 , nc2 = expr . args_cnc ( ) <EOL> repl_dict = repl_dict . copy ( ) <EOL> if c1 : <EOL> if not c2 : <EOL> c2 = [ <NUM_LIT:1> ] <EOL> a = self . func ( * c1 ) <EOL> if isinstance ( a , AssocOp ) : <EOL> repl_dict = a . _matches_commutative ( self . func ( * c2 ) , repl_dict , old ) <EOL> else : <EOL> repl_dict = a . matches ( self . func ( * c2 ) , repl_dict ) <EOL> if repl_dict : <EOL> a = self . func ( * nc1 ) <EOL> if isinstance ( a , self . func ) : <EOL> repl_dict = a . _matches ( self . func ( * nc2 ) , repl_dict ) <EOL> else : <EOL> repl_dict = a . matches ( self . func ( * nc2 ) , repl_dict ) <EOL> return repl_dict or None <EOL> def _matches ( self , expr , repl_dict = { } ) : <EOL> from sympy import Wild <EOL> sign = <NUM_LIT:1> <EOL> a , b = self . as_two_terms ( ) <EOL> if a is S . NegativeOne : <EOL> if b . is_Mul : <EOL> sign = - sign <EOL> else : <EOL> return b . matches ( - expr , repl_dict ) <EOL> expr = sympify ( expr ) <EOL> if expr . is_Mul and expr . args [ <NUM_LIT:0> ] is S . NegativeOne : <EOL> expr = - expr <EOL> sign = - sign <EOL> if not expr . is_Mul : <EOL> if len ( self . args ) == <NUM_LIT:2> : <EOL> if b == expr : <EOL> return a . matches ( Rational ( sign ) , repl_dict ) <EOL> dd = b . matches ( expr , repl_dict ) <EOL> if dd is None : <EOL> return None <EOL> dd = a . matches ( Rational ( sign ) , dd ) <EOL> return dd <EOL> return None <EOL> d = repl_dict . copy ( ) <EOL> pp = list ( self . args ) <EOL> ee = list ( expr . args ) <EOL> for p in self . args : <EOL> if p in expr . args : <EOL> ee . remove ( p ) <EOL> pp . remove ( p ) <EOL> if len ( pp ) == <NUM_LIT:1> and isinstance ( pp [ <NUM_LIT:0> ] , Wild ) : <EOL> if len ( ee ) == <NUM_LIT:1> : <EOL> d [ pp [ <NUM_LIT:0> ] ] = sign * ee [ <NUM_LIT:0> ] <EOL> else : <EOL> d [ pp [ <NUM_LIT:0> ] ] = sign * expr . func ( * ee ) <EOL> return d <EOL> if len ( ee ) != len ( pp ) : <EOL> return None <EOL> for p , e in zip ( pp , ee ) : <EOL> d = p . xreplace ( d ) . matches ( e , d ) <EOL> if d is None : <EOL> return None <EOL> return d <EOL> @ staticmethod <EOL> def _combine_inverse ( lhs , rhs ) : <EOL> """<STR_LIT>""" <EOL> if lhs == rhs : <EOL> return S . One <EOL> def check ( l , r ) : <EOL> if l . is_Float and r . is_comparable : <EOL> return l . __add__ ( <NUM_LIT:0> ) == r . evalf ( ) . __add__ ( <NUM_LIT:0> ) <EOL> return False <EOL> if check ( lhs , rhs ) or check ( rhs , lhs ) : <EOL> return S . One <EOL> if lhs . is_Mul and rhs . is_Mul : <EOL> a = list ( lhs . args ) <EOL> b = [ <NUM_LIT:1> ] <EOL> for x in rhs . args : <EOL> if x in a : <EOL> a . remove ( x ) <EOL> elif - x in a : <EOL> a . remove ( - x ) <EOL> b . append ( - <NUM_LIT:1> ) <EOL> else : <EOL> b . append ( x ) <EOL> return lhs . func ( * a ) / rhs . func ( * b ) <EOL> return lhs / rhs <EOL> def as_powers_dict ( self ) : <EOL> d = defaultdict ( int ) <EOL> for term in self . args : <EOL> b , e = term . as_base_exp ( ) <EOL> d [ b ] += e <EOL> return d <EOL> def as_numer_denom ( self ) : <EOL> numers , denoms = list ( zip ( * [ f . as_numer_denom ( ) for f in self . args ] ) ) <EOL> return self . func ( * numers ) , self . func ( * denoms ) <EOL> def as_base_exp ( self ) : <EOL> e1 = None <EOL> bases = [ ] <EOL> nc = <NUM_LIT:0> <EOL> for m in self . args : <EOL> b , e = m . as_base_exp ( ) <EOL> if not b . is_commutative : <EOL> nc += <NUM_LIT:1> <EOL> if e1 is None : <EOL> e1 = e <EOL> elif e != e1 or nc > <NUM_LIT:1> : <EOL> return self , S . One <EOL> bases . append ( b ) <EOL> return self . func ( * bases ) , e1 <EOL> def _eval_is_polynomial ( self , syms ) : <EOL> return all ( term . _eval_is_polynomial ( syms ) for term in self . args ) <EOL> def _eval_is_rational_function ( self , syms ) : <EOL> return all ( term . _eval_is_rational_function ( syms ) for term in self . args ) <EOL> def _eval_is_algebraic_expr ( self , syms ) : <EOL> return all ( term . _eval_is_algebraic_expr ( syms ) for term in self . args ) <EOL> _eval_is_finite = lambda self : _fuzzy_group ( <EOL> a . is_finite for a in self . args ) <EOL> _eval_is_commutative = lambda self : _fuzzy_group ( <EOL> a . is_commutative for a in self . args ) <EOL> _eval_is_complex = lambda self : _fuzzy_group ( <EOL> ( a . is_complex for a in self . args ) , quick_exit = True ) <EOL> def _eval_is_infinite ( self ) : <EOL> if any ( a . is_infinite for a in self . args ) : <EOL> if any ( a . is_zero for a in self . args ) : <EOL> return S . NaN . is_infinite <EOL> if any ( a . is_zero is None for a in self . args ) : <EOL> return None <EOL> return True <EOL> def _eval_is_rational ( self ) : <EOL> r = _fuzzy_group ( ( a . is_rational for a in self . args ) , quick_exit = True ) <EOL> if r : <EOL> return r <EOL> elif r is False : <EOL> return self . is_zero <EOL> def _eval_is_algebraic ( self ) : <EOL> r = _fuzzy_group ( ( a . is_algebraic for a in self . args ) , quick_exit = True ) <EOL> if r : <EOL> return r <EOL> elif r is False : <EOL> return self . is_zero <EOL> def _eval_is_zero ( self ) : <EOL> zero = infinite = False <EOL> for a in self . args : <EOL> z = a . is_zero <EOL> if z : <EOL> if infinite : <EOL> return <EOL> zero = True <EOL> else : <EOL> if not a . is_finite : <EOL> if zero : <EOL> return <EOL> infinite = True <EOL> if zero is False and z is None : <EOL> zero = None <EOL> return zero <EOL> def _eval_is_integer ( self ) : <EOL> is_rational = self . is_rational <EOL> if is_rational : <EOL> n , d = self . as_numer_denom ( ) <EOL> if d is S . One : <EOL> return True <EOL> elif d is S ( <NUM_LIT:2> ) : <EOL> return n . is_even <EOL> elif is_rational is False : <EOL> return False <EOL> def _eval_is_polar ( self ) : <EOL> has_polar = any ( arg . is_polar for arg in self . args ) <EOL> return has_polar and all ( arg . is_polar or arg . is_positive for arg in self . args ) <EOL> def _eval_is_real ( self ) : <EOL> return self . _eval_real_imag ( True ) <EOL> def _eval_real_imag ( self , real ) : <EOL> zero = one_neither = False <EOL> for t in self . args : <EOL> if not t . is_complex : <EOL> return t . is_complex <EOL> elif t . is_imaginary : <EOL> real = not real <EOL> elif t . is_real : <EOL> if not zero : <EOL> z = t . is_zero <EOL> if not z and zero is False : <EOL> zero = z <EOL> elif z : <EOL> if all ( a . is_finite for a in self . args ) : <EOL> return True <EOL> return <EOL> elif t . is_real is False : <EOL> if one_neither : <EOL> return <EOL> one_neither = True <EOL> else : <EOL> return <EOL> if one_neither : <EOL> if real : <EOL> return zero <EOL> elif zero is False : <EOL> return real <EOL> elif real : <EOL> return real <EOL> def _eval_is_imaginary ( self ) : <EOL> z = self . is_zero <EOL> if z : <EOL> return False <EOL> elif z is False : <EOL> return self . _eval_real_imag ( False ) <EOL> def _eval_is_hermitian ( self ) : <EOL> return self . _eval_herm_antiherm ( True ) <EOL> def _eval_herm_antiherm ( self , real ) : <EOL> one_nc = zero = one_neither = False <EOL> for t in self . args : <EOL> if not t . is_commutative : <EOL> if one_nc : <EOL> return <EOL> one_nc = True <EOL> if t . is_antihermitian : <EOL> real = not real <EOL> elif t . is_hermitian : <EOL> if not zero : <EOL> z = t . is_zero <EOL> if not z and zero is False : <EOL> zero = z <EOL> elif z : <EOL> if all ( a . is_finite for a in self . args ) : <EOL> return True <EOL> return <EOL> elif t . is_hermitian is False : <EOL> if one_neither : <EOL> return <EOL> one_neither = True <EOL> else : <EOL> return <EOL> if one_neither : <EOL> if real : <EOL> return zero <EOL> elif zero is False or real : <EOL> return real <EOL> def _eval_is_antihermitian ( self ) : <EOL> z = self . is_zero <EOL> if z : <EOL> return False <EOL> elif z is False : <EOL> return self . _eval_herm_antiherm ( False ) <EOL> def _eval_is_irrational ( self ) : <EOL> for t in self . args : <EOL> a = t . is_irrational <EOL> if a : <EOL> others = list ( self . args ) <EOL> others . remove ( t ) <EOL> if all ( ( x . is_rational and fuzzy_not ( x . is_zero ) ) is True for x in others ) : <EOL> return True <EOL> return <EOL> if a is None : <EOL> return <EOL> return False <EOL> def _eval_is_positive ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _eval_pos_neg ( <NUM_LIT:1> ) <EOL> def _eval_pos_neg ( self , sign ) : <EOL> saw_NON = saw_NOT = False <EOL> for t in self . args : <EOL> if t . is_positive : <EOL> continue <EOL> elif t . is_negative : <EOL> sign = - sign <EOL> elif t . is_zero : <EOL> if all ( a . is_finite for a in self . args ) : <EOL> return False <EOL> return <EOL> elif t . is_nonpositive : <EOL> sign = - sign <EOL> saw_NON = True <EOL> elif t . is_nonnegative : <EOL> saw_NON = True <EOL> elif t . is_positive is False : <EOL> sign = - sign <EOL> if saw_NOT : <EOL> return <EOL> saw_NOT = True <EOL> elif t . is_negative is False : <EOL> if saw_NOT : <EOL> return <EOL> saw_NOT = True <EOL> else : <EOL> return <EOL> if sign == <NUM_LIT:1> and saw_NON is False and saw_NOT is False : <EOL> return True <EOL> if sign < <NUM_LIT:0> : <EOL> return False <EOL> def _eval_is_negative ( self ) : <EOL> if self . args [ <NUM_LIT:0> ] == - <NUM_LIT:1> : <EOL> return ( - self ) . is_positive <EOL> return self . _eval_pos_neg ( - <NUM_LIT:1> ) <EOL> def _eval_is_odd ( self ) : <EOL> is_integer = self . is_integer <EOL> if is_integer : <EOL> r , acc = True , <NUM_LIT:1> <EOL> for t in self . args : <EOL> if not t . is_integer : <EOL> return None <EOL> elif t . is_even : <EOL> r = False <EOL> elif t . is_integer : <EOL> if r is False : <EOL> pass <EOL> elif acc != <NUM_LIT:1> and ( acc + t ) . is_odd : <EOL> r = False <EOL> elif t . is_odd is None : <EOL> r = None <EOL> acc = t <EOL> return r <EOL> elif is_integer is False : <EOL> return False <EOL> def _eval_is_even ( self ) : <EOL> is_integer = self . is_integer <EOL> if is_integer : <EOL> return fuzzy_not ( self . is_odd ) <EOL> elif is_integer is False : <EOL> return False <EOL> def _eval_is_prime ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . is_number : <EOL> """<STR_LIT>""" <EOL> r = S . One <EOL> for arg in self . args : <EOL> r *= arg <EOL> return r . is_prime <EOL> if self . is_integer and self . is_positive : <EOL> """<STR_LIT>""" <EOL> number_of_args = <NUM_LIT:0> <EOL> for arg in self . args : <EOL> if ( arg - <NUM_LIT:1> ) . is_positive : <EOL> number_of_args += <NUM_LIT:1> <EOL> if number_of_args > <NUM_LIT:1> : <EOL> return False <EOL> def _eval_subs ( self , old , new ) : <EOL> from sympy . functions . elementary . complexes import sign <EOL> from sympy . ntheory . factor_ import multiplicity <EOL> from sympy . simplify . powsimp import powdenest <EOL> from sympy . simplify . radsimp import fraction <EOL> if not old . is_Mul : <EOL> return None <EOL> if old . args [ <NUM_LIT:0> ] . is_Number and old . args [ <NUM_LIT:0> ] < <NUM_LIT:0> : <EOL> if self . args [ <NUM_LIT:0> ] . is_Number : <EOL> if self . args [ <NUM_LIT:0> ] < <NUM_LIT:0> : <EOL> return self . _subs ( - old , - new ) <EOL> return None <EOL> def base_exp ( a ) : <EOL> from sympy import exp <EOL> if a . is_Pow or a . func is exp : <EOL> return a . as_base_exp ( ) <EOL> return a , S . One <EOL> def breakup ( eq ) : <EOL> """<STR_LIT>""" <EOL> ( c , nc ) = ( defaultdict ( int ) , list ( ) ) <EOL> for a in Mul . make_args ( eq ) : <EOL> a = powdenest ( a ) <EOL> ( b , e ) = base_exp ( a ) <EOL> if e is not S . One : <EOL> ( co , _ ) = e . as_coeff_mul ( ) <EOL> b = Pow ( b , e / co ) <EOL> e = co <EOL> if a . is_commutative : <EOL> c [ b ] += e <EOL> else : <EOL> nc . append ( [ b , e ] ) <EOL> return ( c , nc ) <EOL> def rejoin ( b , co ) : <EOL> """<STR_LIT>""" <EOL> ( b , e ) = base_exp ( b ) <EOL> return Pow ( b , e * co ) <EOL> def ndiv ( a , b ) : <EOL> """<STR_LIT>""" <EOL> if not b . q % a . q or not a . q % b . q : <EOL> return int ( a / b ) <EOL> return <NUM_LIT:0> <EOL> rv = None <EOL> n , d = fraction ( self ) <EOL> self2 = self <EOL> if d is not S . One : <EOL> self2 = n . _subs ( old , new ) / d . _subs ( old , new ) <EOL> if not self2 . is_Mul : <EOL> return self2 . _subs ( old , new ) <EOL> if self2 != self : <EOL> rv = self2 <EOL> co_self = self2 . args [ <NUM_LIT:0> ] <EOL> co_old = old . args [ <NUM_LIT:0> ] <EOL> co_xmul = None <EOL> if co_old . is_Rational and co_self . is_Rational : <EOL> if co_old != co_self : <EOL> co_xmul = co_self . extract_multiplicatively ( co_old ) <EOL> elif co_old . is_Rational : <EOL> return rv <EOL> ( c , nc ) = breakup ( self2 ) <EOL> ( old_c , old_nc ) = breakup ( old ) <EOL> if co_xmul and co_xmul . is_Rational and abs ( co_old ) != <NUM_LIT:1> : <EOL> mult = S ( multiplicity ( abs ( co_old ) , co_self ) ) <EOL> c . pop ( co_self ) <EOL> if co_old in c : <EOL> c [ co_old ] += mult <EOL> else : <EOL> c [ co_old ] = mult <EOL> co_residual = co_self / co_old ** mult <EOL> else : <EOL> co_residual = <NUM_LIT:1> <EOL> ok = True <EOL> if len ( old_nc ) > len ( nc ) : <EOL> ok = False <EOL> elif len ( old_c ) > len ( c ) : <EOL> ok = False <EOL> elif set ( i [ <NUM_LIT:0> ] for i in old_nc ) . difference ( set ( i [ <NUM_LIT:0> ] for i in nc ) ) : <EOL> ok = False <EOL> elif set ( old_c ) . difference ( set ( c ) ) : <EOL> ok = False <EOL> elif any ( sign ( c [ b ] ) != sign ( old_c [ b ] ) for b in old_c ) : <EOL> ok = False <EOL> if not ok : <EOL> return rv <EOL> if not old_c : <EOL> cdid = None <EOL> else : <EOL> rat = [ ] <EOL> for ( b , old_e ) in old_c . items ( ) : <EOL> c_e = c [ b ] <EOL> rat . append ( ndiv ( c_e , old_e ) ) <EOL> if not rat [ - <NUM_LIT:1> ] : <EOL> return rv <EOL> cdid = min ( rat ) <EOL> if not old_nc : <EOL> ncdid = None <EOL> for i in range ( len ( nc ) ) : <EOL> nc [ i ] = rejoin ( * nc [ i ] ) <EOL> else : <EOL> ncdid = <NUM_LIT:0> <EOL> take = len ( old_nc ) <EOL> limit = cdid or S . Infinity <EOL> failed = [ ] <EOL> i = <NUM_LIT:0> <EOL> while limit and i + take <= len ( nc ) : <EOL> hit = False <EOL> rat = [ ] <EOL> for j in range ( take ) : <EOL> if nc [ i + j ] [ <NUM_LIT:0> ] != old_nc [ j ] [ <NUM_LIT:0> ] : <EOL> break <EOL> elif j == <NUM_LIT:0> : <EOL> rat . append ( ndiv ( nc [ i + j ] [ <NUM_LIT:1> ] , old_nc [ j ] [ <NUM_LIT:1> ] ) ) <EOL> elif j == take - <NUM_LIT:1> : <EOL> rat . append ( ndiv ( nc [ i + j ] [ <NUM_LIT:1> ] , old_nc [ j ] [ <NUM_LIT:1> ] ) ) <EOL> elif nc [ i + j ] [ <NUM_LIT:1> ] != old_nc [ j ] [ <NUM_LIT:1> ] : <EOL> break <EOL> else : <EOL> rat . append ( <NUM_LIT:1> ) <EOL> j += <NUM_LIT:1> <EOL> else : <EOL> ndo = min ( rat ) <EOL> if ndo : <EOL> if take == <NUM_LIT:1> : <EOL> if cdid : <EOL> ndo = min ( cdid , ndo ) <EOL> nc [ i ] = Pow ( new , ndo ) * rejoin ( nc [ i ] [ <NUM_LIT:0> ] , <EOL> nc [ i ] [ <NUM_LIT:1> ] - ndo * old_nc [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) <EOL> else : <EOL> ndo = <NUM_LIT:1> <EOL> l = rejoin ( nc [ i ] [ <NUM_LIT:0> ] , nc [ i ] [ <NUM_LIT:1> ] - ndo * <EOL> old_nc [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) <EOL> mid = new <EOL> ir = i + take - <NUM_LIT:1> <EOL> r = ( nc [ ir ] [ <NUM_LIT:0> ] , nc [ ir ] [ <NUM_LIT:1> ] - ndo * <EOL> old_nc [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] ) <EOL> if r [ <NUM_LIT:1> ] : <EOL> if i + take < len ( nc ) : <EOL> nc [ i : i + take ] = [ l * mid , r ] <EOL> else : <EOL> r = rejoin ( * r ) <EOL> nc [ i : i + take ] = [ l * mid * r ] <EOL> else : <EOL> nc [ i : i + take ] = [ l * mid ] <EOL> limit -= ndo <EOL> ncdid += ndo <EOL> hit = True <EOL> if not hit : <EOL> failed . append ( i ) <EOL> i += <NUM_LIT:1> <EOL> else : <EOL> if not ncdid : <EOL> return rv <EOL> failed . extend ( range ( i , len ( nc ) ) ) <EOL> for i in failed : <EOL> nc [ i ] = rejoin ( * nc [ i ] ) . subs ( old , new ) <EOL> if cdid is None : <EOL> do = ncdid <EOL> elif ncdid is None : <EOL> do = cdid <EOL> else : <EOL> do = min ( ncdid , cdid ) <EOL> margs = [ ] <EOL> for b in c : <EOL> if b in old_c : <EOL> e = c [ b ] - old_c [ b ] * do <EOL> margs . append ( rejoin ( b , e ) ) <EOL> else : <EOL> margs . append ( rejoin ( b . subs ( old , new ) , c [ b ] ) ) <EOL> if cdid and not ncdid : <EOL> margs = [ Pow ( new , cdid ) ] + margs <EOL> return co_residual * self2 . func ( * margs ) * self2 . func ( * nc ) <EOL> def _eval_nseries ( self , x , n , logx ) : <EOL> from sympy import Order , powsimp <EOL> terms = [ t . nseries ( x , n = n , logx = logx ) for t in self . args ] <EOL> res = powsimp ( self . func ( * terms ) . expand ( ) , combine = '<STR_LIT>' , deep = True ) <EOL> if res . has ( Order ) : <EOL> res += Order ( x ** n , x ) <EOL> return res <EOL> def _eval_as_leading_term ( self , x ) : <EOL> return self . func ( * [ t . as_leading_term ( x ) for t in self . args ] ) <EOL> def _eval_conjugate ( self ) : <EOL> return self . func ( * [ t . conjugate ( ) for t in self . args ] ) <EOL> def _eval_transpose ( self ) : <EOL> return self . func ( * [ t . transpose ( ) for t in self . args [ : : - <NUM_LIT:1> ] ] ) <EOL> def _eval_adjoint ( self ) : <EOL> return self . func ( * [ t . adjoint ( ) for t in self . args [ : : - <NUM_LIT:1> ] ] ) <EOL> def _sage_ ( self ) : <EOL> s = <NUM_LIT:1> <EOL> for x in self . args : <EOL> s *= x . _sage_ ( ) <EOL> return s <EOL> def as_content_primitive ( self , radical = False , clear = True ) : <EOL> """<STR_LIT>""" <EOL> coef = S . One <EOL> args = [ ] <EOL> for i , a in enumerate ( self . args ) : <EOL> c , p = a . as_content_primitive ( radical = radical , clear = clear ) <EOL> coef *= c <EOL> if p is not S . One : <EOL> args . append ( p ) <EOL> return coef , self . func ( * args ) <EOL> def as_ordered_factors ( self , order = None ) : <EOL> """<STR_LIT>""" <EOL> cpart , ncpart = self . args_cnc ( ) <EOL> cpart . sort ( key = lambda expr : expr . sort_key ( order = order ) ) <EOL> return cpart + ncpart <EOL> @ property <EOL> def _sorted_args ( self ) : <EOL> return tuple ( self . as_ordered_factors ( ) ) <EOL> def prod ( a , start = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> return reduce ( operator . mul , a , start ) <EOL> def _keep_coeff ( coeff , factors , clear = True , sign = False ) : <EOL> """<STR_LIT>""" <EOL> if not coeff . is_Number : <EOL> if factors . is_Number : <EOL> factors , coeff = coeff , factors <EOL> else : <EOL> return coeff * factors <EOL> if coeff is S . One : <EOL> return factors <EOL> elif coeff is S . NegativeOne and not sign : <EOL> return - factors <EOL> elif factors . is_Add : <EOL> if not clear and coeff . is_Rational and coeff . q != <NUM_LIT:1> : <EOL> q = S ( coeff . q ) <EOL> for i in factors . args : <EOL> c , t = i . as_coeff_Mul ( ) <EOL> r = c / q <EOL> if r == int ( r ) : <EOL> return coeff * factors <EOL> return Mul . _from_args ( ( coeff , factors ) ) <EOL> elif factors . is_Mul : <EOL> margs = list ( factors . args ) <EOL> if margs [ <NUM_LIT:0> ] . is_Number : <EOL> margs [ <NUM_LIT:0> ] *= coeff <EOL> if margs [ <NUM_LIT:0> ] == <NUM_LIT:1> : <EOL> margs . pop ( <NUM_LIT:0> ) <EOL> else : <EOL> margs . insert ( <NUM_LIT:0> , coeff ) <EOL> return Mul . _from_args ( margs ) <EOL> else : <EOL> return coeff * factors <EOL> def expand_2arg ( e ) : <EOL> from sympy . simplify . simplify import bottom_up <EOL> def do ( e ) : <EOL> if e . is_Mul : <EOL> c , r = e . as_coeff_Mul ( ) <EOL> if c . is_Number and r . is_Add : <EOL> return _unevaluated_Add ( * [ c * ri for ri in r . args ] ) <EOL> return e <EOL> return bottom_up ( e , do ) <EOL> from . numbers import Rational <EOL> from . power import Pow <EOL> from . add import Add , _addsort , _unevaluated_Add </s>
