假设您有类似
的功能F = lambda x: sin(x)/x
评估F(0.0)
会导致除以零警告,并且不会给出1.0
的预期结果。是否可以编写另一个函数fix_singularity
,当应用于上述函数时,它将提供所需的结果,以便
fix_singularity(F)(0.0) == 1.0
或正式fix_singularity
应通过以下测试:
import numpy as np
def test_fix_singularity():
F = lambda x: np.sin(x)/x
x = np.array((0.0, pi))
np.testing.assert_array_almost_equal( F(x), [nan, 0] )
np.testing.assert_array_almost_equal( fix_singularity(F)(x), [1, 0] )
一种可能的实施方式是
def fix_singularity(F):
""" Fix the singularity of function F(x) """
def L(x):
f = F(x)
i = np.isnan(f)
f[i] = F(x[i] + 1e-16)
return f
return L
有更好的方法吗?
编辑: 另外我如何禁止警告:
Warning: invalid value encountered in divide
答案 0 :(得分:7)
numpy
有一个sinc()
函数,它是函数的规范化形式,即
F = lambda x: sin(pi*x) / (pi*x)
正确处理x == 0.0
的情况,
In [16]: x = numpy.linspace(-1,1,11)
In [17]: print x
[-1. -0.8 -0.6 -0.4 -0.2 0. 0.2 0.4 0.6 0.8 1. ]
“unnormalize”do,
In [22]: s = numpy.sinc(x/numpy.pi)
In [23]: print s.round(2)
[ 0.84 0.9 0.94 0.97 0.99 1. 0.99 0.97 0.94 0.9 0.84]
答案 1 :(得分:3)
如果您已经在使用numpy,那么:
a = np.linspace(0.0,2*np.pi,100)
b = np.sin(a)/a
在NaN
中保留b[0]
值时会毫无错误地计算。如果你想要处理它,你可以用以下内容替换它:
b[np.isnan(b)] = 1.0
更新要取消警告,请尝试:
np.seterr(divide='ignore') # Or possibly np.seterr(invalid='ignore')
答案 2 :(得分:2)
一般来说,你不能像想象的那样编写一个简单的修复装饰器。例如,一般函数不需要在奇点处具有有限的极限值,如该特定示例那样。
通常的做法是根据具体情况实施特殊处理。
答案 3 :(得分:1)
我会试试这个
>>> def fix_singularity(F):
... def L(x):
... x1 = max(x,1e-16) if x >=0 else min(x,-1e-16)
... return F(x1)
... return L
...
>>> FS = fix_singularity(F)
>>> FS(0.0)
1.0
>>> FS(-1e-17)
1.0
答案 4 :(得分:0)
我不知道这是否适用于您的确切目的,但是有一个名为sage的python库可以处理相当多的微积分类型的情况。
答案 5 :(得分:0)
我相信sympy(符号python)可以做限制,这就是你真正要求的(该解决方案仅作为限制)。无论如何,你应该看看它。