Comment #7 on issue 1358 by wflynny: (e*f*e*f).subs(e*f,f*e+h) fails if e*f is not commutative http://code.google.com/p/sympy/issues/detail?id=1358
Okay. I'm not sure how to exactly patch so I'll just post the code I wrote. I end up using the first portion of yaukwankiu's code from above. Anyway, here is the replaced _eval_subs method: def _eval_subs(self, old, new): if self == old: return new if isinstance(old, FunctionClass): return self.__class__(*[s._eval_subs(old, new) for s in self.args ]) coeff_self,terms_self = self.as_coeff_terms() coeff_old,terms_old = old.as_coeff_terms() if terms_self == terms_old: # (2*a).subs(3*a,y) -> 2/3*y return new * coeff_self/coeff_old # BEGIN: MY PATCH 6/11/09 l_temp = [] #temporary for i in terms_old: if i.is_Pow and type(i.exp) is Integer: for j in range(i.exp): l_temp.append(i.base) #convert (...h**2...) to (...h,h...) else: l_temp.append(i) terms_old=tuple(l_temp) l_temp = [] #temporary for i in terms_self: if i.is_Pow and type(i.exp) is Integer: for j in range(i.exp): l_temp.append(i.base) #convert (...h**2...) to (...h,h...) else: l_temp.append(i) terms_self=tuple(l_temp) l1, l2 = len(terms_self), len(terms_old) if l2 == 0: # if old is just a number, go through the self.args one by one return Mul(*[x._eval_subs(old, new) for x in self.args]) elif l2 < l1: self_set = [element for element in terms_self] old_set = [element for element in terms_old] len_old = len(terms_old) len_self = len(terms_self) temp = [] if len(old_set) < len(self_set): # Scan through list of self for i in range(len_self): # If a member of self matches the first in the set to be replaced # Scan through the list of to-be-replaced set and make sure the # Next terms all match. If they don't, break. if self_set[i] == old_set[0]: for j in range(len_old): if self_set[i+j] != old_set[j]: for k in range(i,i+j): temp.append(self_set[k]) break elif j == len_old - 1: temp.append(new) for k in range(i+j+1,len_self): temp.append(self_set[k]) return Mul(coeff_self/coeff_old, *[element for element in temp])._eval_subs(old,new) else: temp.append(self_set[i]) return Mul(coeff_self/coeff_old, *[element for element in temp]) # END: MY PATCH ATTEMPT 6/10/09 return self.__class__(*[s._eval_subs(old, new) for s in self.args]) It passes the following tests: import sympy as sp def subs_test(): # Define symbols t,w,x,y,z = sp.symbols('twxyz',commutative=False) # Start off easy a = x*y b = y*x # Add some noise c = w*x*y*z # Double d = x*y*x*y # Hard e = x*x*y # Hardest f = x*x*y*y assert a.subs(x*y,t) == t; print 'test A passed' assert b.subs(x*y,t) == y*x; print 'test B passed' assert c.subs(x*y,t) == w*t*z; print 'test C passed' assert d.subs(x*y,t) == t**2; print 'test D passed' assert e.subs(x*y,t) == x*t; print 'test E passed' assert f.subs(x*y,t) == x*t*y; print 'test F passed' subs_test() Let me know if this helps! -wflynn -- You received this message because you are listed in the owner or CC fields of this issue, or because you starred this issue. You may adjust your issue notification preferences at: http://code.google.com/hosting/settings --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy-issues" group. To post to this group, send email to sympy-issues@googlegroups.com To unsubscribe from this group, send email to sympy-issues+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy-issues?hl=en -~----------~----~----~----~------~----~------~--~---