#NEWLINE# def _matches_commutative( self , expr , repl_dict = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } , old = False ) : #NEWLINE# #INDENT# '\n        Matches Add/Mul "pattern" to an expression "expr".\n\n        repl_dict ... a dictionary of (wild: expression) pairs, that get\n                      returned with the results\n\n        This function is the main workhorse for Add/Mul.\n\n        For instance:\n\n        >>> from sympy import symbols, Wild, sin\n        >>> a = Wild("a")\n        >>> b = Wild("b")\n        >>> c = Wild("c")\n        >>> x, y, z = symbols("x y z")\n        >>> (a+sin(b)*c)._matches_commutative(x+sin(y)*z)\n        {a_: x, b_: y, c_: z}\n\n        In the example above, "a+sin(b)*c" is the pattern, and "x+sin(y)*z" is\n        the expression.\n\n        The repl_dict contains parts that were already matched. For example\n        here:\n\n        >>> (x+sin(b)*c)._matches_commutative(x+sin(y)*z, repl_dict={a: x})\n        {a_: x, b_: y, c_: z}\n\n        the only function of the repl_dict is to return it in the\n        result, e.g. if you omit it:\n\n        >>> (x+sin(b)*c)._matches_commutative(x+sin(y)*z)\n        {b_: y, c_: z}\n\n        the "a: x" is not returned in the result, but otherwise it is\n        equivalent.\n\n        ' #NEWLINE# from . expr import Add , Expr #NEWLINE# from sympy import Mul #NEWLINE# if ( isinstance ( self , Expr ) and ( not isinstance ( expr , Expr ) ) ) : #NEWLINE# #INDENT# return None #NEWLINE# #UNINDENT# if ( self == expr ) : #NEWLINE# #INDENT# return repl_dict #NEWLINE# #UNINDENT# d = self . _matches_simple ( expr , repl_dict ) #NEWLINE# if ( d is not None ) : #NEWLINE# #INDENT# return d #NEWLINE# #UNINDENT# from . function import WildFunction #NEWLINE# from . symbol import Wild #NEWLINE# wild_part = [ ] #NEWLINE# exact_part = [ ] #NEWLINE# for p in ordered ( self . args ) : #NEWLINE# #INDENT# if ( p . has ( Wild , WildFunction ) and ( not expr . has ( p ) ) ) : #NEWLINE# #INDENT# wild_part . append ( p ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# exact_part . append ( p ) #NEWLINE# #UNINDENT# #UNINDENT# if exact_part : #NEWLINE# #INDENT# exact = self . func ( * exact_part ) #NEWLINE# free = expr . free_symbols #NEWLINE# if ( free and ( exact . free_symbols - free ) ) : #NEWLINE# #INDENT# return None #NEWLINE# #UNINDENT# newpattern = self . func ( * wild_part ) #NEWLINE# newexpr = self . _combine_inverse ( expr , exact ) #NEWLINE# if ( ( not old ) and ( expr . is_Add or expr . is_Mul ) ) : #NEWLINE# #INDENT# if ( newexpr . count_ops ( ) > expr . count_ops ( ) ) : #NEWLINE# #INDENT# return None #NEWLINE# #UNINDENT# #UNINDENT# return newpattern . matches ( newexpr , repl_dict ) #NEWLINE# #UNINDENT# i = 0 #NEWLINE# saw = set ( ) #NEWLINE# while ( expr not in saw ) : #NEWLINE# #INDENT# saw . add ( expr ) #NEWLINE# expr_list = ( ( self . identity , ) + tuple ( ordered ( self . make_args ( expr ) ) ) ) #NEWLINE# for last_op in reversed ( expr_list ) : #NEWLINE# #INDENT# for w in reversed ( wild_part ) : #NEWLINE# #INDENT# d1 = w . matches ( last_op , repl_dict ) #NEWLINE# if ( d1 is not None ) : #NEWLINE# #INDENT# d2 = self . xreplace ( d1 ) . matches ( expr , d1 ) #NEWLINE# if ( d2 is not None ) : #NEWLINE# #INDENT# return d2 #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# if ( i == 0 ) : #NEWLINE# #INDENT# if self . is_Mul : #NEWLINE# #INDENT# if ( expr . is_Pow and expr . exp . is_Integer ) : #NEWLINE# #INDENT# if ( free . exp > 0 ) : #NEWLINE# #INDENT# expr = Mul ( * [ expr . base , ( expr . base ** ( expr . exp - 1 ) ) ] , evaluate = False ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# expr = Mul ( * [ ( 1 / expr . base ) , ( expr . base ** ( expr . exp + 1 ) ) ] , evaluate = False ) #NEWLINE# #UNINDENT# i += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if self . is_Add : #NEWLINE# #INDENT# ( c , e ) = expr . as_coeff_Mul ( ) #NEWLINE# if ( abs ( c ) > 1 ) : #NEWLINE# #INDENT# if ( c > 0 ) : #NEWLINE# #INDENT# expr = Add ( * [ e , ( ( c - 1 ) * e ) ] , evaluate = False ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# expr = Add ( * [ ( - e ) , ( ( c + 1 ) * e ) ] , evaluate = False ) #NEWLINE# #UNINDENT# i += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# from sympy.simplify.radsimp import collect #NEWLINE# was = expr #NEWLINE# did = set ( ) #NEWLINE# for w in reversed ( wild_part ) : #NEWLINE# #INDENT# ( c , w ) = w . as_coeff_mul ( Wild ) #NEWLINE# free = ( c . free_symbols - did ) #NEWLINE# if free : #NEWLINE# #INDENT# did . update ( free ) #NEWLINE# expr = collect ( expr , free ) #NEWLINE# #UNINDENT# #UNINDENT# if ( expr != was ) : #NEWLINE# #INDENT# i += 0 #NEWLINE# continue #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# break #NEWLINE# #UNINDENT# #UNINDENT# return