2012-10-11 55 views
3

我正在寫一些matlab代碼,並且寫了一個可行的算法,但我不認爲它特別有效。因爲我正在努力提高自己的編程技能,所以我想知道是否有更高效的方法來做到這一點。在Matlab中更有效地循環使用矩陣元素

我有一個(相當大的〜E07)矩陣的值是無序的,但落在範圍[-100,100]之內。我想基於所述第一以創建第二矩陣,通過使用下面的規則:

  1. 如果點的值是> 70,則點的值應該被設置爲70。
  2. 如果該點的值爲< -70,那麼該點的值應該設置爲-70。
  3. 所有其他的值應四捨五入至5

這裏最接近的倍數就是我目前在做:

data = 100*(-1+2*rand(1,10000000)); % create random dataset for stackoverflow 
new_data = zeros(1,length(data)); 

for i = 1:length(data) 
    if (data(i) > 70) 
     new_data(i) = 70; 
    elseif (data(i) < -70) 
     new_data(i) = -70; 
    else 
     new_data(i) = round(data(i)/5.0)*5.0; 
    end 
end 

有沒有更有效的方法?我覺得應該有一個辦法做到這一點使用邏輯索引,但這些對我來說是一個新的發現......

回答

8

你並不需要一個循環都:

data = 100*(-1+2*rand(1,10000000)); % create random dataset for stackoverflow 
new_data = zeros(1,length(data)); % note that this memory allocation is not necessary at this point 

new_data = round(data/5.0)*5.0; 
new_data(data>70) = 70;  
new_data(data<-70) = -70; 
+0

這也正是這樣的事情,我想!謝謝:) – FakeDIY

5

即使是更容易使用max和分鐘。在一條簡單的線路中完成。

new_data = round(5*max(-70,min(70,data)))/5; 
+0

不錯的一行。 –

+0

不錯。我更喜歡@H的可讀性。Muster的回答,但我認爲這一個班輪計算更有效率。謝謝。 – FakeDIY

+0

+1比第一個答案快,但可以改進:) – angainor

2

H.Muster和woodchips的兩個答案當然是這樣做的方式,但仍然有小的改進。如果你在表現之後,你可能想利用你的問題的細節。例如,您的輸出數據是整數-100 <= x <= 100。這顯然適用於8位有符號整數數據類型。這個代碼(音符顯式轉換到int8從任意雙精度數據)

% your double precision input data 
data = 100*(-1+2*rand(1,10000000)); 

% cast to int8 - matlab does usual round here 
data = int8(data); 
new_data = 5*(max(-70,min(70,data))/5); 

是最快的,原因有二:

  • 1數據元素採用1個字節,而不是8內存帶寬是一個限制因素在這裏,所以你得到了很多的改進
  • 輪不再需要

下面是H.Muster,木屑,的代碼一些定時的nd我小修改:

H.Muster Elapsed time is 0.235885 seconds. 
woodchips Elapsed time is 0.167659 seconds. 
my code  Elapsed time is 0.023061 seconds. 

區別是相當驚人的。雖然MATLAB採用雙打無處不在,你應該嘗試儘可能使用整數數據類型..

編輯這工作,因爲Matlab中如何實現整數運算。不同於在C,雙int的鑄鐵意味着round操作:

a = 0.1; 
int8(a) 

ans = 
    0 

a = 0.9; 
int8(a) 

ans = 
    1 
+0

有趣,謝謝。我實際上正在處理的數據並不是一個整數,但他們都是雙打。 – FakeDIY

+0

@FKEDIY我顯然不夠清楚:)爲其他人輸入相同的雙輸入數據。它給出了相同的結果。你的輸入數據不需要是整數 - 主要的是你的**輸出**數據是。我對'uint8'使用了一個明確的類型轉換,它初始舍入並且是方法的一部分。簡而言之,對於您生成的測試數據,所有方法都會得到相同的結果。 – angainor

+0

啊,有你。數據類型並不是我知道的很多東西---多數民衆贊成在一個非常好的方法。 :-) – FakeDIY