如何将包含erf函数的SymPy表达式转换为可与NumPy一起使用的lambda函数

5

我希望使用SymPy将包含erf函数的符号表达式进行Lambda化。对于标量参数,可以执行以下操作:

log_normal = 0.5 + 0.5 * sym.erf((sym.log(x) - mu) / sym.sqrt(2 * sigma**2))
F = sym.lambdify([x, mu, sigma], log_normal)
F(1.0, 0.0, 1.0)

我想要对上述内容进行矢量化处理。通常情况下,我会按照以下方式进行操作...
log_normal = 0.5 + 0.5 * sym.erf((sym.log(x) - mu) / sym.sqrt(2 * sigma**2))
vector_F = sym.lambdify([x, mu, sigma], log_normal, modules='numpy')
vector_F(1.0, 0.0, 1.0)

然而,上述问题引发了一个“NameError”(名称错误)...
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-29-14adde48d4a1> in <module>()
----> 1 vector_F(1.0, 0.0, 1.0)

/Users/drpugh/anaconda/lib/python2.7/site-packages/numpy/__init__.pyc in <lambda>(x, mu,     sigma)

NameError: global name 'erf' is not defined

这是一个bug,还是我漏掉了一些微不足道的东西?

2个回答

3
从SymPy 1.3开始,在lambdify中自动支持scipy。如果省略modules参数,则会自动添加scipy,或者您可以使用modules = ['numpy','scipy']
>>> log_normal = 0.5 + 0.5 * sym.erf((sym.log(x) - mu) / sym.sqrt(2 * sigma**2))
>>> vector_F = sym.lambdify([x, mu, sigma], log_normal)
>>> vector_F(1.0, 0.0, 1.0)
0.5

通常,要支持一个 lambdify 不知道的函数,请将它作为字典添加到 modules 参数中。 modules 参数确定了 lambdified 函数运行的命名空间。有关详细信息,请参阅lambdify文档。例如,要在 SymPy < 1.3 中支持 erf:

>>> import scipy.special
>>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy', {'erf': scipy.special.erf}])
>>> vector_F(1.0, 0.0, 1.0)
0.5

3

你告诉 lambdify 它只能使用 numpy 模块; 给它一个 erf 的来源。也就是说,你有:

>>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy'])
>>> vector_F(1.0, 0.0, 1.0)
Traceback (most recent call last):
  File "<ipython-input-10-14adde48d4a1>", line 1, in <module>
    vector_F(1.0, 0.0, 1.0)
  File "<string>", line 1, in <lambda>
NameError: global name 'erf' is not defined

但是。
>>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy', 'sympy'])
>>> vector_F(1.0, 0.0, 1.0)
0.500000000000000

或者

>>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy', 'math'])
>>> vector_F(1.0, 0.0, 1.0)
0.5

或者你喜欢哪个erf,这取决于你是否想要一个sympy.core.numbers.Float还是float


4
您可以使用 modules=['numpy', {'erf': scipy.special.erf}] 来使用Scipy的 erf函数。 - asmeurer
@asmeurer 我认为这条评论应该作为单独的答案。对我来说,使用erf并不起作用。然而,使用你的解决方案确实有效。 - NichtJens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接