Hey everyone,
Let's say I defined my own sympy.Symbol called MySymbol2. For some reason subs using a string doesn't always work, but it works for sympy.Symbol.
This is version 0.7.4.1. I have a 0.7.3 example below that works fine. I see that the function fallback in core.py was changed.
from is not test on line 992 in 0.7.3:
if arg is not args[i]
to not equal test on line 1036 in
0.7.4.1:
if arg != args[i]:
>>> class MySymbol2(sympy.Symbol): pass
>>> expr = MySymbol2('A') * (MySymbol2('X') > 5)
>>> print expr.subs({'X':10})
A*(X > 5)
>>> expr = sympy.Symbol('A') * (sympy.Symbol('X') > 5)
>>> print expr.subs({'X':10})
A*True
Sometimes the subs work fine. Below X and Y are both substituted for my MySymbol
>>> expr = sympy.sympify('3*X + Y')
>>> subsDic2 = {'X': MySymbol2('X'), 'Y': MySymbol2('Y')}
>>> expr2 = expr.subs(subsDic2)
>>> print [(i, type(i)) for i in expr2.atoms()]
[(X, <class 'stats.tests.modelSymbolicTest.MySymbol2'>), (3, <class 'sympy.core.numbers.Integer'>), (Y, <class 'stats.tests.modelSymbolicTest.MySymbol2'>)]
I've tried a fix like:
class MySymbolWithNameEq(sympy.Symbol):
def __eq__(self, other):
if isinstance(other, sympy.Symbol):
else:
return sympy.Symbol.__eq__(self, other)
but that causes the subs on 3*X+Y to fail and my A*(X>5) still fails. Notice that not all the atoms are replaced.
>>> expr = MySymbolWithNameEq('A') * (MySymbolWithNameEq('X') > 5)
>>> print expr.subs({'X':10})
A*(X > 5)
>>> subsDic3 = {'X': MySymbolWithNameEq('X'), 'Y': MySymbolWithNameEq('Y')}
>>> expr = sympy.sympify('3*X + Y')
>>> expr2 = expr.subs(subsDic3)
>>> print [(i, type(i)) for i in expr2.atoms()]
[(Y, <class 'stats.tests.modelSymbolicTest.MySymbolWithNameEq'>), (X, <class 'sympy.core.symbol.Symbol'>), (3, <class 'sympy.core.numbers.Integer'>)]
#on 0.7.3 the above works correctly
>>> expr2 = expr.subs(subsDic3)
>>> print [(i, type(i)) for i in expr2.atoms()]
[(X, <class 'stats.tests.modelSymbolicTest.MySymbolWithNameEq'>), (3, <class 'sympy.core.numbers.Integer'>), (Y, <class 'stats.tests.modelSymbolicTest.MySymbolWithNameEq'>)]
Any idea how to inherit from sympy.Symbol while still getting string substitution to work reliably?
thanks,
Rob