实现numpy.sin(x)/ x的最佳方法,其中x可能包含0

时间:2016-03-31 02:17:52

标签: python numpy

我现在正在做的是:

import numpy as np

eps = np.finfo(float).eps

def sindiv(x):
    x = np.abs(x)
    return np.maximum(eps, np.sin(x)) / np.maximum(eps, x)

但是还有很多额外的数组操作。还有更好的方法吗?

3 个答案:

答案 0 :(得分:5)

您可以使用numpy.sinc来计算sin(pi x)/(pi x):

In [20]: x = 2.4

In [21]: np.sin(x)/x
Out[21]: 0.28144299189631289

In [22]: x_over_pi = x / np.pi

In [23]: np.sinc(x_over_pi)
Out[23]: 0.28144299189631289

In [24]: np.sinc(0)
Out[24]: 1.0

答案 1 :(得分:1)

以numpy数组表示法(所以你得到一个np数组):

def sindiv(x):
    return np.where(np.abs(x) < 0.01, 1.0 - x*x/6.0, np.sin(x)/x)

在这里,我对“epsilon”进行了相当大的测试,并使用了泰勒系列的前两个项来进行近似。在实践中,我会将0.01更改为eps(机器epsilon)的一小部分。

xx = np.arange(-0.1, 0.1, 0.001)
yy = sinxdiv(xx)
type(yy)

输出numpy.ndarray,并且值在原点附近是连续的(并且可区分,如果这很重要)。

如果你不想进行双重评估(即两个分支都在上面评估),那么我认为你必须使用循环,因为我不相信有任何“懒惰的地方”选项。

def sindiv(x):
    sox = np.zeros(x.size)
    for i in xrange(x.size):
        xv = x[i]
        if np.abs(xv) < 0.001: # For testing, use a small multiple of machine epsilon
            sox[i] = 1.0 - xv * xv / 6.0
        else:
            sox[i] = np.sin(xv) / xv
    return sox

为了使这个真正pythonic虽然最好检查x的类型,如果它不是一个数组,只做非数组版本。

答案 2 :(得分:0)

如果允许div为零并稍后替换NaN?

import numpy as np

def sindiv(x):
    a = np.sin(x)/x
    a = np.nan_to_num(a)
    return a

如果您不想要警告,请通过seterr

对其进行压制

当然,使用a可以消除:

def sindiv(x):
    return np.nan_to_num(np.sin(x)/x)