修复函数的奇点

时间:2011-04-05 18:50:46

标签: python numpy nan singular

假设您有类似

的功能
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 个答案:

答案 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)可以做限制,这就是你真正要求的(该解决方案仅作为限制)。无论如何,你应该看看它。