Хорошо, надеюсь, название имело какой-то смысл. Я сделал код быстрого преобразования Фурье и хочу посмотреть, как он может быть на go быстрее. Итак, вот код ('code1'), в котором я выполняю замену, как диктует БПФ:
stp='''
import numpy as nn
D=2**18
N=12
w=(nn.linspace(0,D-1,D)%2**N<(2**N/2))-.5 #square wave
f=w[0:2**N]+nn.zeros(2**N)*1j #it takes only one wavelength from w
'''
code1='''
for m in range(N):
for l in range(2**m):
for k in range(2**(N-1-m)):
t=f[k+l*2**(N-m)]
f[k+l*2**(N-m)]=(t+f[k+l*2**(N-m)+2**(N-1-m)])
f[k+l*2**(N-m)+2**(N-1-m)]=(t-f[k+l*2**(N-m)+2**(N-1-m)])*nn.e**(-2*nn.pi*1j*k*2**(m)/2**N)
'''
print(timeit.timeit(setup=stp,stmt=code1,number=1))
, где я ввожу новую переменную 't'. Это выводит время 0,132.
Итак, я подумал, что он должен go быстрее, если бы я сделал (настройка такая же, как и раньше):
code2='''
for m in range(N):
for l in range(2**m):
for k in range(2**(N-1-m)):
f[k+l*2**(N-m)],f[k+l*2**(N-m)+2**(N-1-m)]=f[k+l*2**(N-m)]+f[k+l*2**(N-m)+2**(N-1-m)],(f[k+l*2**(N-m)]-f[k+l*2**(N-m)+2**(N-1-m)])*nn.e**(-2*nn.pi*1j*k*2**(m)/2**N)
'''
print(timeit.timeit(setup=stp,stmt=code2,number=1))
, так как теперь я выполняю два назначения вместо из трех (я так думал). Но похоже, что на самом деле это медленнее (0,152). У кого-нибудь есть идея, почему? И знает ли кто-нибудь способ сделать эту замену быстрее, чем t=a,a=f(a,b),b=g(t,b)
, который я представил ранее, поскольку мне трудно поверить, что это наиболее эффективный способ.
EDIT: добавлен фактический код вместо псевдокод.
БОЛЬШЕ РЕДАКТИРОВАНИЯ: я пробовал запустить то же самое, не используя Numpy. Оба они быстрее, так что это положительно, но снова метод t=a,a=f(a,b),b=g(t,b)
оказывается быстрее (0,104), чем метод a,b=f(a,b),g(a,b)
(0,114). Так что загадка остается.
новый код:
stpsansnumpy='''
import cmath as mm
D=2**18
N=12
w=[0]*D
for i in range(D):
w[i]=(i%2**N<(2**N/2))-.5 #square wave
f=w[0:2**N]+[0*1j]*2**N #it takes only one wavelength from w
'''
code1math='''
for m in range(N):
for l in range(2**m):
for k in range(2**(N-1-m)):
t=f[k+l*2**(N-m)]
f[k+l*2**(N-m)]=(t+f[k+l*2**(N-m)+2**(N-1-m)])
f[k+l*2**(N-m)+2**(N-1-m)]=(t-f[k+l*2**(N-m)+2**(N-1-m)])*mm.exp(-2*mm.pi*1j*k*2**(m)/2**N)
'''
print(timeit.timeit(setup=stpsansnumpy,stmt=code1math,number=1))
и:
code2math='''
for m in range(N):
for l in range(2**m):
for k in range(2**(N-1-m)):
f[k+l*2**(N-m)],f[k+l*2**(N-m)+2**(N-1-m)]=f[k+l*2**(N-m)]+f[k+l*2**(N-m)+2**(N-1-m)],(f[k+l*2**(N-m)]-f[k+l*2**(N-m)+2**(N-1-m)])*mm.exp(-2*mm.pi*1j*k*2**(m)/2**N)
'''
print(timeit.timeit(setup=stpsansnumpy,stmt=code2math,number=1))