从表达式中分类自由符号

时间:2014-12-18 00:46:21

标签: python sympy

假设我有两个Symbol对象fg,我可以合理地假设它们代表函数。我不知道这两个函数是先验的,但是据我所知,g的定义是这样的:

g = symbols('1')

用户忽略指定cls=Number,以便g.free_symbols给我set([1])(也许用户并不熟悉SymPy)。如果我在集合中收集fg的所有免费符号,然后尝试计算它们的雅可比行列式,我最终会在矩阵中添加一个额外的列来表示f的导数和g相对于1,这是无稽之谈。

如何将数字检测为未明确声明为数字的Symbol对象,以避免出现这种情况?

3 个答案:

答案 0 :(得分:1)

你可以通过sympify传递表达的str:

>>> eq = Symbol('x') + Symbol('1')
>>> eq.atoms(Number)
set([])
>>> sympify(str(eq))
x + 1
>>> _.atoms(Number)
set([1])

答案 1 :(得分:1)

更有针对性的方法是使用替换:

仅定位数字

>>> eq.replace(
... lambda x: x.is_Symbol and S(x.name).is_Number,
... lambda x: S(x.name))
x + 1
>>> _.atoms(Number)
set([1])

定位任意数字表达式

>>> Symbol('1+2').replace(
... lambda x: x.is_Symbol and S(x.name).is_Number,
... lambda x: S(x.name))
3

定位任何表达

>>> Symbol('1+x').replace(
... lambda x: S(x.name).is_Symbol is False,
... lambda x: S(x.name))
x + 1

答案 2 :(得分:0)

您可以检查每个符号的名称,看看它是否像数字:

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)))

输出:

s =  x False
s =  2 True       -- looks like a number

然后,或许,您希望将这些符号替换为数值以消除它们。

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)

输出:

x + 3