【发布时间】:2020-05-10 03:32:06
【问题描述】:
我的印象是复数乘法比实数乘法需要更长的时间,因为它需要3 multiplications。
但是我尝试了以下方法:
a, b = 3, 4
c, d = 5, 6
print(a*c - b*d, a*d + b*c)
e = 3+4j
f = 5+6j
print(e*f)
%timeit a*c - b*d
%timeit a*d + b*c
%timeit e*f
%timeit a*b
得到了
-9 38
(-9+38j)
110 ns ± 0.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
102 ns ± 0.193 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
47.2 ns ± 0.942 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
43 ns ± 1.52 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
为什么复数乘法几乎和实数复数一样快?
我知道 Python 是一门高级语言,但这个结果仍然让我感到困惑......
我能想到的唯一解释是,我的两种计算都达到了如此低的速度,以至于瓶颈不是计算本身,而是其他东西..
这是我想问的原始问题
我有这个版本的离散傅里叶变换,它使用复杂的运算:
from math import e, pi, cos, sin, log2
def W(n, N):
theta = n * -1 * 2 * pi / N
return cos(theta) + 1j*sin(theta)
def dft(signal):
N = len(signal)
total = []
for k in range(N):
s = 0
for n in range(N):
s += signal[n] * W(n*k, N)
total.append(s)
return total
我也有这个版本的 DFT,它不使用复杂运算,而是使用两个实数信号,因为信号的虚部被编码到实数数组中。
def Wri(n, N):
theta = n * -1 * 2 * pi / N
return cos(theta), sin(theta)
def dft_ri(signal_r, signal_i):
N = len(signal_r)
tr, ti = [], []
for k in range(N):
sr = 0
si = 0
for n in range(N):
a = signal_r[n]
b = signal_i[n]
c, d = Wri(n*k, N)
sr += a*c - b*d
si += a*d + b*c
tr.append(sr)
ti.append(si)
return tr, ti
使用以下复数信号
x = np.linspace(0, T, 1024)
def signal2(t):
return np.where(np.logical_and((t%T>=0), (t%T<np.pi)), t%T+t%T*1j, np.pi+np.pi*1j)
s = list(signal2(x))
sr = list(np.real(s))
si = list(np.imag(s))
两个 W 花费的时间大致相同
%timeit W(8, 3)
%timeit Wri(8, 3)
输出
464 ns ± 0.756 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
424 ns ± 2.21 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
然而
%timeit dft(s)
%timeit dft_ri(sr, si)
输出
935 ms ± 4.63 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1.6 s ± 3.04 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
问题
为什么没有复杂运算的 DFT 所花费的时间几乎是具有复杂运算的 DFT 的两倍?
【问题讨论】:
标签: python performance complex-numbers