簡體   English   中英

Matlab 效率:小for-loop

[英]Matlab efficiency: small for-loop

我寫了一些 Matlab 代碼,到目前為止可以工作,但是在使用大矩陣運行時非常慢。 我將代碼的瓶頸確定為 for 循環。

代碼應該做的是查看 H 矩陣的一列 (ic),與至少有一個與 ic 相同的 1 條目的其他列進行比較,並將它們的列添加到 ic 向量中。 這種情況會一直發生,直到 ic 向量不再發生變化。

這是一個小例子:

H = ( 1 0 1; 1 1 0; 0 0 1 ) 和 ic = ( 1 1 0 )^T (H 的第一列)。 然后代碼以 ic 的第一個 1 為例,在其行中比較另一列是否也有 1 作為其第一個條目,找到第三列 ( 1 0 1 )^T 然后將所有這些添加到 ic 向量在找到的列中,在這種情況下是第三個條目,因此 ic = ( 1 1 1 )^T。

起初我使用了兩個 for 循環:

H是一個 (500 x 1000) 稀疏矩陣(但當代碼運行得更快時應該是 (5000 x 10 000))。

ic是 (500 x 1) 向量。

i是代碼開頭的 ic 向量的索引。

代碼1(舊版本):

for c = find(ic).'
     for v = find(H(c,:))
          if v ~= i
              ic = ic | H(:,v);
          end
     end
end

然后我嘗試改進我的代碼並通過矢量化使其更快:

代碼2(新版本):

for c = find(ic).'
     ic( sum(H(:,find(H(c,:))'),2) > 0 ) = 1;
end

第二行代碼2調用了1769302次,占用了97.4%的時間,也就是30.568s。 它被調用了很多次,因為 ic 向量必須在構造 H 矩陣時確定,並且幾乎在 H 矩陣中添加任何 1 之前被調用。 與代碼 1 相比,時間已經有所改善,其中第二行耗時 20.209 秒,第四行耗時 31.950 秒。 我的目標是使用 (5000 x 10 000) H 矩陣運行我的代碼,並且不超過 3 分鍾。

H 矩陣是在代碼運行時構建的。 在添加到矩陣中的幾乎每個 1 之前,都會調用其中包含上述代碼的 function。 然后 ic 向量在 while 循環中更新,直到它不再變化或 ic 向量中不再有零。 while 循環如下所示:

代碼 3(上下文):

ic2 = ic;

while true

     for c = find(ic).'
          ic( sum(H(:,find(H(c,:))'),2) > 0 ) = 1;
     end
     
     if isequal(ic0,ic)
          return;
     end
     ic0 = ic;

     if sum(ic(:,1)) == size(H,1)
          return;
     else
          ic2 = ic;
     end

end

ic0的唯一目的是比較迭代之間的ic

ic2保存了ic的 state 之前它只包含一個。

我非常感謝任何可以幫助我進一步改善代碼運行時間的答案,我很抱歉在 Matlab 編程方面經驗不足。 非常感謝您的任何回答!

我想這取決於你是否想在添加一個之后再次檢查整個 ic 向量。 因為如果您在向量中的某個點添加一個,您已經處理過,您可能會與其他列有一些新的連接。 但是,如果您不想再次檢查,在將一個添加到 ic 矢量后,您可以使用以下內容:

H = [ 1 0 1 ; 
      1 1 0 ; 
      0 0 1 ];
  
ic = [1; 
      1; 
      0];

Htemp = H+ic;

ic = any(H(:, any(Htemp>1)),2);
  

要檢查直到 ic 不再改變,您可以嘗試以下操作:

ic = H(:,1);
a = true;
s = 0;
ic2 = ic;
while a
    Htemp   = H+ic;
    ic      = any(H(:, any(Htemp>1)),2);
    Htemp   = H+ic;
    if s == sum(ic)
        a = false;
    else
        s = sum(ic);
        a = true;
    end
    if sum(ic(:,1)) == size(H,1)
        return;
    else
        ic2 = ic;
    end
end

對於我的隨機矩陣,這不會通過 while 循環進行兩次以上的迭代,但它應該完全按照您上面的代碼所做的,只是更快。 計算大約需要 0.9 秒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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