Pieter wrote:
>> Dear newsgroup,
>>
>> I am trying to generate common sub expressions from an equation, but
>> the results are incorrect for negative values of the symbols.
>> An example (sympy 0.6.7)
>>
>>
>> x1=Symbol('x1')
>> x2=Symbol('x2')
>> y1=Symbol('y1')
>> z=Symbol('z', negative=True)
>>
>> eq=x1*(1+ y1*(x1**2/z**2+x2**2/z**2))/z
>> v1,v2=cse(eq)
>> print(eq)
>> print(v1)
>> print(v2)
>>
>> For x1=1, x2=1, y1=0 and z=-1 the original equation and the value of
>> the cse expression yield different values.
>>
>> Is this a bug in cse, or can I make certain assumptions on the
>> symbols to generate correct expressions?
>>
This is happening because the substitutions of the repeated pattern (z**2) are
targetting the z. This is a known issue that I am working on; my subs_cleanup
branch is a first step toward this. Here's a nuisance-level fix (not robust for
every type of sympy object but should work for plain algebraic expressions):
def esub(eq, reps):
'''make exact replacements in eq using the old/new key/value
pairs of reps'''
if eq in reps:
return reps[eq]
args = list(eq.args)
if not args:
return eq
for i, a in enumerate(args):
args[i] = esub(a, reps)
return eq.func(*args)
>>> esub(eq, dict([(v, k) for k, v in v1])) # what cse should give
x1*(1 + y1*(x0*x1**2 + x0*x2**2))/z
>>> eq.subs({x1:1,x2:1,y1:0,z:-1}) # original
-1
>>> esub(eq, dict([(v, k) for k, v in v1])).subs({x1:1,x2:1,y1:0,z:-1}) #
esub-cse
-1
/chris
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to [email protected].
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.