我现在正在做的是:
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)
但是还有很多额外的数组操作。还有更好的方法吗?
答案 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)