Reputation: 179
Suppose I am given two Symbol objects, f
and g
, which I can reasonably assume represent functions. I don't know a priori what these two functions are, but say that without my knowledge, g
was defined like so:
g = symbols('1')
where the user has neglected to specify cls=Number
so that g.free_symbols
gives me set([1])
(maybe the user isn't intimately familiar with SymPy). If I collect all the free symbols of f
and g
in a set, and then attempt to compute their Jacobian, I end up with an extra column in the matrix representing the derivatives of f
and g
with respect to 1, which is nonsense.
How can I detect numbers as Symbol objects which are not explicitly declared to be numbers so as to avoid such a scenario?
Upvotes: 1
Views: 365
Reputation: 19093
A more targeted approach would use replace:
Target only Numbers
>>> eq.replace(
... lambda x: x.is_Symbol and S(x.name).is_Number,
... lambda x: S(x.name))
x + 1
>>> _.atoms(Number)
set([1])
Target any number expression
>>> Symbol('1+2').replace(
... lambda x: x.is_Symbol and S(x.name).is_Number,
... lambda x: S(x.name))
3
Target any expression
>>> Symbol('1+x').replace(
... lambda x: S(x.name).is_Symbol is False,
... lambda x: S(x.name))
x + 1
Upvotes: 1
Reputation: 19093
You could pass the str of the expression through sympify:
>>> eq = Symbol('x') + Symbol('1')
>>> eq.atoms(Number)
set([])
>>> sympify(str(eq))
x + 1
>>> _.atoms(Number)
set([1])
Upvotes: 1
Reputation: 52049
You could inspect the name of each symbol and see if it looks like a number:
import sympy as sp
import re
x = sp.Symbol('x')
g = sp.Symbol('2')
f = x + 1
h = f + g
for s in h.free_symbols:
print "s = ", s, bool(re.match('^[0-9]+$', str(s)))
Output:
s = x False
s = 2 True -- looks like a number
Perhaps, then, you want to substitute numeric values back for those symbols to eliminate them.
def eliminate_numbers(f):
for s in f.free_symbols:
assigns = {}
if re.match('^-?[0-9]+$', str(s)):
assigns[s] = int( str(s) )
return f.subs(assigns)
print eliminate_numbers(h)
Output:
x + 3
Upvotes: 0