[英]Speed Up MATLAB for Fourier Series For Loop
我知道這個話題已被多次訪問過,所以請提前道歉。 我只是無法解決效率低下的循環操作,並希望得到你的幫助。
我正在實現一個for循環,它對時域周期數據求和。 我使用從先前FFT獲得的傅里葉系數。 我的問題是我需要在周期信息中添加額外的時域數據,所以我不能簡單地使用逆FFT運算。 我基本上編輯標准的離散傅立葉變換(DFT)和,即:
for k = 1:L
x = x + F(k+1)*exp(1j*(omega(k+1)*t));
end
在這個系列中,F是我的傅立葉系數,omega是頻率向量,t是時間向量。 我必須改變總和,使它看起來像這樣:
for k = 1:L
x = x + F(k+1)*exp(1j*(omega(k+1)*t)+1j*k*xt);
end
唯一的變化是我現在包括一個向量,它是一個時域函數(例如正弦波),我稱之為xt。 問題是時域信息必須具有極其精細的分辨率(10秒記錄大約5e6長)。 我無法縮短時間長度,因為我需要高頻分辨率。 這導致我的機器上的單個功能評估大約7小時(我必須承認,這不是最好的)。 我需要在優化設置中評估功能,因此7小時的功能評估時間是不可行的。
我試圖對操作進行矢量化,但是矩陣變得太大而我的計算機無法處理,並且MATLAB已經更新以便更有效地處理循環。 我曾嘗試編寫自己的快速傅里葉變換版本,但是因為我在每一步編輯頻率信息,Cooley和Tukey算法需要分解的某些假設。 有誰知道如何將上述總和重寫成更有效的格式? 我也預先分配了矢量。
那么,問題:
循環很慢,但解決了可用內存中的問題;
矢量化很快,但會占用你的記憶;
我不能發布代碼,因為你提供的關於 但是混合解決方案如何:您可以在可以進行矢量化的頻率間隔中分割問題,並在整個頻率間隔(塊)而不是每個頻率上累積部分解決方案。 就像是: F
, omega
, t
和xt
外觀的細節太少(即值的確切大小和范圍),
%%
clear all; % [!] BEWARE BEFORE EXECUTING, IT DELETES STUFF!!!
N = 1016419;
R = 524288;
t = linspace(1,10,N);
F = 400*rand(1,R) + 200i*rand(1,R);
omega = 1./(1:R);
xt = sin(0.23*t);
x = zeros(size(xt));
U = 10;
% ck1 = repmat(1i*t, U, 1); % trying to be extra clever is
% ck2 = repmat(1i*xt, U, 1); % not always good for the health
ck1 = 1i*t;
ck2 = 1i*xt;
u0 = 1;
tic;
while u0 < R
u1 = min(u0+U-1,R);
% x = x + sum(bsxfun( ...
% @times, ...
% F(u0+1:u1+1).', ...
% exp(omega(u0+1:u1+1).' * ck1 ...
% + (u0+1:u1+1).' * ck2 ...
% ) ...
% ));
x = x + sum(bsxfun( ...
@times, ...
F(u0+1:u1+1).', ...
exp(bsxfun(@times, ck1, omega(u0+1:u1+1).') ...
+ bsxfun(@times, ck2, (u0+1:u1+1).') ...
) ...
));
u0 = u1 + 1;
fprintf('%d iterations: %.0f sec.\n', u1, toc);
end;
U
的值應該足夠小,因此xu
貢獻的矢量化版本適合存儲器,並且足夠大以使矢量化成為重要的。 所以你需要進行一些實驗。
我認為這可能是一種使用bsxfun
實現你想要的矢量化方法。
k = 1:L;
x = x + sum(bsxfun(@times, F(k+1), exp(1j*(bsxfun(@times, omega(k+1), permute(t, [2 1])) + bsxfun(@times, k, permute(xt, [2 1]))))), 2).';
注意 :對於這個解F
, omega
, k
, t
和xt
都應該是列向量,即1x?
。
首先計算指數exp(1j*(omega(k+1)*t)+1j*k*xt)
e = exp(1j*(bsxfun(@times, omega(k+1), permute(t, [2 1])) + bsxfun(@times, k, permute(xt, [2 1]))))
它產生一個MxL
矩陣,其中M
是t
和xt
的長度。 接下來,我們將每列乘以F
(尺寸為1xL
) 1xL
Fe = bsxfun(@times, F(k+1), e)
這是另一個MxL
矩陣。 最后,我們沿第二維( L
)求和以產生Mx1
向量
x = x + sum(Fe, 2).'
哪里.'
用於將Mx1
向量轉置為1xM
向量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.