--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---

Fix for Mul._eval_subs

Before:

In [2]: (a*b*c).subs(a*c,b)
Out[2]: a⋅b⋅c

After:

In [2]: (a*b*c).subs(a*c,b)
Out[2]:
 2
b

diff --git a/sympy/core/mul.py b/sympy/core/mul.py
--- a/sympy/core/mul.py
+++ b/sympy/core/mul.py
@@ -605,28 +605,28 @@
             return False
 
     def _eval_subs(self, old, new):
-        if self==old:
+        if self == old:
             return new
         if isinstance(old, FunctionClass):
             return self.__class__(*[s.subs(old, new) for s in self.args ])
-        coeff1,terms1 = self.as_coeff_terms()
-        coeff2,terms2 = old.as_coeff_terms()
-        if terms1==terms2: # (2*a).subs(3*a,y) -> 2/3*y
-            return new * coeff1/coeff2
-        l1,l2 = len(terms1),len(terms2)
+        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
+        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.subs(old, new) for x in self.args])
-        elif l2<l1:
+        elif l2 < l1:
             # old is some something more complex, like:
             # (a*b*c*d).subs(b*c,x) -> a*x*d
             # then we need to search where in self.args the "old" is, and then
             # correctly substitute both terms and coefficients.
-            for i in xrange(l1-l2+1):
-                if terms2==terms1[i:i+l2]:
-                    m1 = Mul(*terms1[:i]).subs(old,new)
-                    m2 = Mul(*terms1[i+l2:]).subs(old,new)
-                    return Mul(*([coeff1/coeff2,m1,new,m2]))
+            self_set = set(terms_self)
+            old_set = set(terms_old)
+            if old_set < self_set:
+                ret_set = self_set - old_set
+                return Mul(new, coeff_self/coeff_old, *[s.subs(old, new) for s in ret_set])
         return self.__class__(*[s.subs(old, new) for s in self.args])
 
     def _eval_nseries(self, x, x0, n):
diff --git a/sympy/core/tests/test_subs.py b/sympy/core/tests/test_subs.py
--- a/sympy/core/tests/test_subs.py
+++ b/sympy/core/tests/test_subs.py
@@ -130,6 +130,11 @@
     assert e.subs(r) == r[a]/r[b] * sin(r[b]*x)
     assert e.subs(r) == 3 * sin(4*x) / 4
 
+def test_mul():
+    x, y, z = map(Symbol, 'xyz')
+    assert (x*y*z).subs(z*x,y) == y**2
+    assert (2*x*y).subs(5*x*y,z) == 2*z/5
+
 def test_add():
     a, b, c, d, x = abc.a, abc.b, abc.c, abc.d, abc.x
     assert (a**2 - b - c).subs(a**2 - b, d) in [d - c, a**2 - b - c]

Reply via email to