私は以下のコードを見直して、チックとトックの間のセクションをスピードアップするヒントを提供したいと考えています。以下の関数は、(1)fft係数ビンの殆どがゼロである(すなわち、,〜300M
個のビンが0でない〜1000
個のビン)、(2)ビンが0であるため、Matlabのビルトイン関数より高速にIFFTを実行しようとします。 IFFT結果の中央3分の1だけが保持されます(最初と最後の3分の1は破棄されるため、最初に計算する必要はありません)。スパースFFT計算の高速化
入力変数は以下のとおりです。
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))
現在、このコードが長く、スペクトル全体がそれの2/3
年代を破棄計算のMatlabのifft
関数アプローチよりも数桁をとります。例えば、fftcoefとビンのための入力データが9x1
配列である場合、(すなわち2^25
)(側波帯あたりすなわちのみ9
複雑なFFT係数の両方の側波帯を考慮した場合18
PTS)、及びDATAn=32781534
、FFTn=33554432
、次にIFFTアプローチは、一方1.6
秒かかり下のループは700
秒を引き継ぎます。
fftcoefとbinsの配列サイズが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
潜在的な節約の分析については、http://www.fftw.org/pruned.htmlを参照してください。それは価値がないかもしれません。 – mtrw
'2 * length(bins)/ 3> lg(DAtan(2 * DATAn/3)')の場合、FFTのアプローチでは 'DATAn * ) '(FFTWは非2の変換サイズを扱うので、私はゼロパディングを無視している)。 10個のビンと2^25の出力ポイントの場合は、'20/3> 25 'であり、潜在的な3倍の改善要因です。あなたが75のFFT coeffになるとすぐに、あなたは優位性を失いました。そして、アルゴリズムをCでコーディングし、それを維持する必要があります。 – mtrw
ありがとうmtrw、私は数日前にリンクを見直しました。 「このため、出力の1%以下を望んでいないかぎり(および/または入力の1%以下がゼロ以外の場合)、刈り込まれた1次元FFTを検討するのはお勧めできません。 "私の場合、入力の0.00001%(IDFTに対する係数)はゼロではありません。私はこれがあなたが上に引用した3つの改善の要因ではなく、スピードの増加の支配的理由であるべきだと思います。 – ggkmath