修复函数的奇点
假设你有一个这样的函数:
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
6 个回答
2
一般来说,你不能像想象中那样简单地写一个 修复 装饰器。比如说,一个通用的函数在某些特殊情况下可能并没有一个固定的限制值,就像这个特定的例子一样。
通常的做法是根据具体情况来进行特别处理。
3
如果你已经在使用numpy的话:
a = np.linspace(0.0,2*np.pi,100)
b = np.sin(a)/a
这样计算不会出错,但会在 b[0]
里留下一个 NaN
的值。你可以用下面的代码来替换它,如果你想这样处理的话:
b[np.isnan(b)] = 1.0
更新 如果你想要不显示警告,可以试试:
np.seterr(divide='ignore') # Or possibly np.seterr(invalid='ignore')
7
numpy
有一个叫 sinc()
的函数,这个函数是你提到的函数的标准化形式,也就是说,它是经过处理的版本。
F = lambda x: sin(pi*x) / (pi*x)
这个函数能正确处理 x == 0.0
的情况,也就是当 x 等于零时,它的表现是没问题的。
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. ]
如果你想把它“反标准化”,可以这样做:
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]