python - skcuda.fft 与 numpy.fft.rfft 不一样?
问题描述
我试图针对 numpy fft 测试 fft 的输出以进行单元测试,但在它失败后不久我意识到,这并不是因为我做错了什么,但 skcuda 字面上并没有产生相同的答案。我知道它们会有所不同,但至少其中一个数字与 numpy 产生的数字相差几个数量级,并且两者都allclose
返回almost_equal
大量错误(对于 33% 和 25%,对于rtol=1e-6
16% atol=1e-6
)。我在这里做错了什么?我可以解决这个问题吗?
测试文件:
import pycuda.autoinit
from skcuda import fft
from pycuda import gpuarray
import numpy as np
def test_skcuda():
array_0 = np.array([[1, 2, 3, 4, 5, 4, 3, 2, 1, 0]], dtype=np.float32)
array_1 = array_0 * 10
time_domain_signal = np.array([array_0[0], array_1[0]], dtype=np.float32)
fft_point_count = 10
fft_plan = fft.Plan(fft_point_count, np.float32, np.complex64,
batch=2)
fft_reserved = gpuarray.empty((2, fft_point_count // 2 + 1), dtype=np.complex64)
fft.fft(gpuarray.to_gpu(time_domain_signal), fft_reserved, fft_plan)
np.testing.assert_array_almost_equal(
np.fft.rfft(time_domain_signal, fft_point_count), fft_reserved.get())
test_skcuda()
断言失败:
AssertionError:
Arrays are not almost equal to 6 decimals
(mismatch 25.0%)
x: array([[ 2.500000e+01+0.000000e+00j, -8.472136e+00-6.155367e+00j,
-1.193490e-15+2.331468e-15j, 4.721360e-01-1.453085e+00j,
2.664535e-15+0.000000e+00j, 1.000000e+00+0.000000e+00j],...
y: array([[ 2.500000e+01+0.000000e+00j, -8.472136e+00-6.155367e+00j,
8.940697e-08+5.960464e-08j, 4.721359e-01-1.453085e+00j,
0.000000e+00+0.000000e+00j, 1.000000e+00+0.000000e+00j],...
打印输出:
#numpy
[[ 2.50000000e+01+0.00000000e+00j -8.47213595e+00-6.15536707e+00j
-1.19348975e-15+2.33146835e-15j 4.72135955e-01-1.45308506e+00j
2.66453526e-15+0.00000000e+00j 1.00000000e+00+0.00000000e+00j]
[ 2.50000000e+02+0.00000000e+00j -8.47213595e+01-6.15536707e+01j
-1.11022302e-14+2.39808173e-14j 4.72135955e+00-1.45308506e+01j
3.55271368e-14+7.10542736e-15j 1.00000000e+01+0.00000000e+00j]]
#skcuda
[[ 2.5000000e+01+0.0000000e+00j -8.4721355e+00-6.1553669e+00j
8.9406967e-08+5.9604645e-08j 4.7213593e-01-1.4530852e+00j
0.0000000e+00+0.0000000e+00j 1.0000000e+00+0.0000000e+00j]
[ 2.5000000e+02+0.0000000e+00j -8.4721359e+01-6.1553673e+01j
1.4305115e-06-4.7683716e-07j 4.7213597e+00-1.4530851e+01j
0.0000000e+00+1.9073486e-06j 1.0000000e+01+0.0000000e+00j]]
解决方案
这看起来很像舍入误差,单精度浮点数有大约 8 个十进制数字精度(双精度有大约 16 个)
而不是使用numpy.fft
替代方案是使用直接支持单精度浮点数fftpack
的scipy,例如:
from scipy import fftpack
x = np.array([1, 2, 3, 4, 5, 4, 3, 2, 1, 0])
y = fftpack.fft(
np.array([x, x * 10], dtype=np.float32)
)
print(y[:,:6])
输出:
[[ 2.5000000e+01+0.0000000e+00j -8.4721355e+00-6.1553669e+00j
8.9406967e-08+5.9604645e-08j 4.7213593e-01-1.4530852e+00j
0.0000000e+00+0.0000000e+00j 1.0000000e+00+0.0000000e+00j]
[ 2.5000000e+02+0.0000000e+00j -8.4721359e+01-6.1553673e+01j
1.1920929e-06+1.9073486e-06j 4.7213583e+00-1.4530851e+01j
0.0000000e+00+1.9073486e-06j 1.0000000e+01+0.0000000e+00j]]
看起来更接近
推荐阅读
- reactjs - 我们如何更改 react.js 中 divX 中存在的按钮的 div Y onclick 的 sass 样式?
- node.js - 如何使用 apollo federation 在 graphql api 网关上设置 redis 缓存?
- javascript - 在第一次尝试时过滤反应查询无法正常工作
- r - 如何在 R 中的 pmax() 中给出一个变量
- react-native - 键盘在反应原生博览会中向上移动视图
- ruby-on-rails - 模型关联问题
- reporting-services - 在 SSRS 报表服务器中对齐?
- vue.js - Vue.js - 通过 npm run serve 在应用程序运行时使用终端
- ssl - 将 Keycloak 用作 WSO2 身份服务器的联合身份提供者时出现 SSL 错误
- linux - 将卷挂载到 sudo 无权访问的 docker