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.

Reply via email to