簡體   English   中英

加速MATLAB for Fourier Series For Loop

[英]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算法需要分解的某些假設。 有誰知道如何將上述總和重寫成更有效的格式? 我也預先分配了矢量。

那么,問題:

  • 循環很慢,但解決了可用內存中的問題;

  • 矢量化很快,但會占用你的記憶;

我不能發布代碼,因為你提供的關於Fomegatxt外觀的細節太少(即值的確切大小和范圍), 但是混合解決方案如何:您可以在可以進行矢量化的頻率間隔中分割問題,並在整個頻率間隔(塊)而不是每個頻率上累積部分解決方案。 就像是:

    %%
    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).';

注意 :對於這個解Fomegaktxt都應該是列向量,即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矩陣,其中Mtxt的長度。 接下來,我們將每列乘以F (尺寸為1xL1xL

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM