2

假设你有一个像

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
4

6 回答 6

7

numpy has a sinc() function, which is the normalised form of your function, i.e.

F = lambda x: sin(pi*x) / (pi*x)

It handles the case for x == 0.0 correctly,

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. ]

To "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]
于 2011-04-05T19:08:49.353 回答
3

如果您已经在使用 numpy,那么:

a = np.linspace(0.0,2*np.pi,100)
b = np.sin(a)/a

将计算没有错误,在 中留下一个NaNb[0]。如果您想这样处理,您可以将其替换为以下内容:

b[np.isnan(b)] = 1.0

更新要禁止警告,请尝试:

np.seterr(divide='ignore') # Or possibly np.seterr(invalid='ignore')
于 2011-04-05T18:52:48.577 回答
2

In general you can't write a simple fix decorator as you might imagine. For example, a general function need not have a finite limiting value at a singularity as this particular example does.

Normal practice is to implement special handling on a case by case basis.

于 2011-04-05T18:59:03.970 回答
1

I'll try this

>>> 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
于 2011-04-05T19:04:07.750 回答
0

I don't know if this would work for your exact purposes, but there's a python library called sage that can handle quite a bit of Calculus-type situations.

于 2011-04-05T18:59:50.600 回答
0

I believe sympy (symbolic python) can do limits, which is what you are really asking (that solution is only true as a limit). Regardless, you should check it out.

于 2011-04-05T19:07:55.700 回答