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
-~----------~----~----~----~------~----~------~--~---

Reply via email to