Поскольку рассматривается дополнение, можно ли увеличить размер дополнения до четного или кратного небольшого числа простых чисел? Выбор четных размеров может разделить время настенных часов на 3.
В зависимости от размеров, некоторые алгоритмы DFT могут быть недоступны или неэффективны.Например, одним из наиболее эффективных алгоритмов выполнения ДПФ является алгоритм Кули-Тьюки .Он состоит в делении ДПФ сигнала составного размера N = N1 * N2 на N1 DTF размера N2.Как следствие, работает лучше для составных размеров, полученных умножением малых простых множителей (2, 3, 5, 7) , для которых в FFTW предусмотрены специальные эффективные алгоритмы.Из документации FFTW :
Например, стандартный дистрибутив FFTW работает наиболее эффективно для массивов, размер которых можно разбить на небольшие простые числа (2, 3, 5 и 7).), а в остальном он использует более медленную процедуру общего назначения.Если вам нужны эффективные преобразования других размеров, вы можете использовать генератор кода FFTW, который создает быстрые C-программы («кодлеты») для любого конкретного размера массива, который вас может заинтересовать.Например, если вам нужны преобразования размером 513 = 19 * 33, вы можете настроить FFTW для эффективной поддержки фактора 19.
Ваши размеры дополнения имеют высокие простые коэффициенты:
931=>962=2*13*37
411=>442=2*13*17
806=>837=3*3*3*31
Заполнение может быть расширено, чтобы приблизиться к числам с небольшими простыми числами, например, например, 980, 448 и 864,Тем не менее, заполнение трехмерного изображения приводит к значительному увеличению объема памяти, до такой степени, что это не всегда возможно.
Почему изменение порядка размеров меняет время вычисления?Разница может быть связана с тем, что входной массив является действительным. Следовательно, DFT R2C выполняется над одним из измерений, затем C2C над вторым и третьим для вычисления 3D DFT.Если размер первого измерения, подлежащего преобразованию, является четным, преобразование R2C можно превратить в сложное ДПФ, равное половине размера, как показано здесь .Этот трюк не работает для нечетного размера.Как следствие, некоторые быстрые алгоритмы, вероятно, станут доступны после переворота 962 и 837.
Вот код для проверки:
import pyfftw
import matplotlib.pyplot as plt
import multiprocessing
import numpy as np
from timeit import default_timer as timer
def listofgoodsizes():
listt=[]
p2=2
for i2 in range(11):
p3=1
for i3 in range(7):
p5=1
for i5 in range(2):
listt.append(p2*p3*p5)
p5*=5
p7=1
for i7 in range(2):
listt.append(p2*p3*p7)
p7*=7
p3*=3
p2*=2
listt.sort()
return listt
def getgoodfftwsize(n,listt):
for i in range(len(listt)):
if listt[i]>=n:
return listt[i]
return n
def timea3DR2CDFT(n,m,p):
bb = pyfftw.empty_aligned((n,m, p), dtype='float64')
bf= pyfftw.empty_aligned((n,m, (p/2+1)), dtype='complex128')
pyfftw.config.NUM_THREADS = 1 #multiprocessing.cpu_count()
fft_object_b = pyfftw.FFTW(bb, bf,axes=(0,1,2))
print n,m,p
start = timer()
fft_object_b(bb)
end = timer()
print end - start
#three prime numbers !
n=3*37
m=241
p=5*19
timea3DR2CDFT(n,m,p)
# to even size :
neven=2*((n+1)/2)
meven=2*((m+1)/2)
peven=2*((p+1)/2)
timea3DR2CDFT(neven,meven,peven)
#to nearest multiple of prime
listt=listofgoodsizes()
ngood=getgoodfftwsize(n,listt)
mgood=getgoodfftwsize(m,listt)
pgood=getgoodfftwsize(p,listt)
timea3DR2CDFT(ngood,mgood,pgood)
На моем компьютере он печатает:
111 241 95
0.180601119995
112 242 96
0.0560319423676
112 252 96
0.0564918518066