Я надеюсь, что кто-то может просмотреть мой код ниже и предложить подсказки, как ускорить раздел между тик и ток. Приведенная ниже функция пытается выполнить IFFT быстрее, чем встроенная функция Matlab, поскольку (1) почти все ячейки с коэффициентом fft равны нулю (т. Е. Ячейки с 10
до 1000
из чисел 10M
до 300M
не ноль), и (2) сохраняется только центральная треть результатов IFFT (первая и последняя треть отбрасываются - поэтому нет необходимости вычислять их в первую очередь).
Входные переменные:
fftcoef = complex fft-coef 1D array (10 to 1000 pts long)
bins = index of fft coefficients corresponding to fftcoef (10 to 1000 pts long)
DATAn = # of pts in data before zero padding and fft (in range of 10M to 260M)
FFTn = DATAn + # of pts used to zero pad before taking fft (in range of 16M to 268M) (e.g. FFTn = 2^nextpow2(DATAn))
В настоящее время этот код занимает на несколько порядков больше, чем функциональный подход Matlab ifft
, который вычисляет весь спектр, а затем отбрасывает 2/3
из него. Например, если входными данными для fftcoef и bin являются 9x1
массивы (т.е. только 9
комплексные коэффициенты fft на боковую полосу; 18
pts при рассмотрении обеих боковых полос) и DATAn=32781534
, FFTn=33554432
(то есть 2^25
), тогда подход ifft занимает 1.6
секунд, тогда как цикл ниже занимает 700
секунд.
Я избегал использования матрицы для векторизации цикла nn, так как иногда размер массива для fftcoef и bin может быть до 1000
pts длиной, а матрица 260Mx1K
будет слишком большой для памяти, если только она не будет как-то расстались.
Любой совет очень ценится! Заранее спасибо.
function fn_fft_v1p0(fftcoef, bins, DATAn, FFTn)
fftcoef = [fftcoef; (conj(flipud(fftcoef)))]; % fft coefficients
bins = [bins; (FFTn - flipud(bins) +2)]; % corresponding fft indices for fftcoef array
ttrend = zeros( (round(2*DATAn/3) - round(DATAn/3) + 1), 1); % preallocate
start = round(DATAn/3)-1;
tic;
for nn = start+1 : round(2*DATAn/3) % loop over desired time indices
% sum over all fft indices having non-zero coefficients
arg = 2*pi*(bins-1)*(nn-1)/FFTn;
ttrend(nn-start) = sum( fftcoef.*( cos(arg) + 1j*sin(arg));
end
toc;
end