考虑以下示例,其中给出了任意数学表达式。
>>> import sympy as sp
>>> expr = sp.sympify("sin(x) + foo(y)")
上面,
sin
是sympy识别的正弦函数(并且可以在求解过程中使用、求值、反转等),但是foo
是sympy未知的函数:
>>> expr.subs('x', sp.pi/2)
foo(y) + 1
>>> expr.subs('y', sp.pi/2)
foo(pi/2) + sin(x)
>>> eq = sp.Eq(sp.sympify('z'), expr)
>>> sp.solve(eq, 'x')
[pi - asin(z - foo(y)), asin(z - foo(y))]
>>> sp.solve(eq, 'z')
[foo(y) + sin(x)]
>>> sp.solve(eq, 'y')
Traceback (most recent call last):
...
NotImplementedError:
No algorithms are implemented to solve equation z - foo(y) - sin(x)
有什么方法可以区分这两个函数“类别”(即 sympy 定义的和非 sympy 定义的)?这样人们就可以用类似的东西提取其中任何一个的所有实例
>>> [func for func in eq.atoms(sp.Function) if is_sympy_defined(func)]
[sin(x)]
>>> [func for func in eq.atoms(sp.Function) if not is_sympy_defined(func)]
[foo(y)]
我比较了两个函数(
sympify('sin(x)')
和 sympify('foo(x)')
)的属性,但似乎没有任何迹象表明其中一个函数是 sympy 定义的,而另一个不是。
谷歌搜索我的标题会出现这篇文章,但它似乎并没有完全按照我想要的方式做(尽管名字听起来合适):
>>> from sympy.core.function import UndefinedFunction
>>> sin = sp.sympify("sin(x)")
>>> isinstance(sin, UndefinedFunction)
>>> False # expected
>>> foo = sp.sympify("foo(x)")
>>> isinstance(foo, UndefinedFunction)
>>> False # unexpected
我认为 API 中没有专用函数来实现这一点,但您可以简单地检查您的函数是否是 sympy.functions:
的一部分import sympy as sp
sin_f = sp.sympify("sin(x + y)")
print(str(sin_f.func) in sp.functions.__all__) #True
foo = sp.sympify("foo(x)")
print(str(foo.func) in sp.functions.__all__) #False
(我将
sin
重命名为 sin_f
以明确 func
指的是底层函数)
调用时未定义的函数是
AppliedUndef
的实例:
In [13]: from sympy.core.function import AppliedUndef
In [14]: e = sympify("sin(x) + foo(y)")
In [15]: e.atoms(Function) # All functions
Out[15]: {foo(y), sin(x)}
In [16]: e.atoms(AppliedUndef) # Undefined functions
Out[16]: {foo(y)}
In [17]: e.atoms(Function) - e.atoms(AppliedUndef) # Defined functions
Out[17]: {sin(x)}