2017-02-06 67 views
-4

我有下面的代碼需要計算3D矩陣的指數。它工作正常,但我不知道是否有反正使它更快。 (目前需要2秒以上,如果可能,我試圖讓它在半秒內運行)。在Matlab中更快的指數計算

Result = zeros(200,50,300); 
for i=1:30 
    delta = i*randn(200,50,300); 
    X = exp(1i*2*pi*delta); 
    Result = Result + X; 
end 

任何幫助,將不勝感激。 在此先感謝。

+2

你是否介紹了該代碼?在那種情況下,'exp'與其他行相比有多少時間?也許問題不在'exp'中。 – mpaskov

+2

我懷疑這將是更快的矢量化。內存消耗本身就會很大。對於涉及大內存的計算,'for'循環更好。 – rayryeng

+1

在你的代碼中,'i'與'1i'不一樣。我希望你已經知道了! –

回答

1

首先,我不認爲這個計算順序可以做得更快。下面可能是一個很小的有點快,但肯定不是由量你正在尋找:

dim = [200,50,300]; % given 
N  = prod(dim); % total number of samples 
M  = 30;   % number of iterations in for-loop 
phase = bsxfun(@times, randn(N,M), [1:M]); % scaled phases 
Result = reshape(sum(exp(1i*2*pi*phase),2), dim); % sum of exp and reshape 

編輯1開始:

正如@horchler在下面的評論中指出,這種方法實際上比R2016b上的原始方法慢。他還建議使用更快的隨機生成方案,我嘗試並觀察到顯着的改進。通過消除一些臨時變量也可以獲得類似的改進。

s = RandStream('dsfmt19937','Seed',1); 
for i=1:30 
    Result = Result + exp(1i*2*pi*i*randn(s,200,50,300)); 
end 

我對優化的各個階段,在R2016b的時序結果,如下:

  • 原始代碼:4.3小號
  • 我原來的建議:4.5小號
  • 原始代碼更簡單隨機數生成:3.8 s
  • 上面的臨時變量刪除:3.2 s

也可以嘗試其他隨機數生成方案,例如shr3cong以努力加速進一步加速。

編輯1:結束

一種不同的方法: 讓我提出一個不同的方法,會產生不同的方式所需要的輸出,但是這樣它會具有相同的統計特性 爲你的輸出。

Result = sqrt(15) * (randn(200,50,300) + 1i*randn(200,50,300)); 

現在我們試着證明這一點。首先,我們可以認爲,由於輸出是30個隨機過程的和,所以通過中心極限定理(CLT),輸出將是高斯分佈的。 CLT只適用於這裏的鬆散意義,因爲30並不是無限的,並且過程不是完全分佈的。但正如我們很快會看到的那樣,它仍然是一個非常好的近似值。此外,實數和虛數項也是獨立的,由於總和超過30個獨立的複數。我不打算在這裏證明這一點,但我們會做一些統計檢查。

一旦我們確定了獨立的高斯分佈,分析變得更加簡單。高斯分佈可以由兩個參數定義:均值和方差。讓我們估計其個人:

平均:由於相位隨機分佈並覆蓋比2*pi更大的區域,對於實部和虛方面的手段是0。

方差:大隨機相位分佈的正弦/餘弦方差爲0.5。所以30個正弦/餘弦之和的方差應爲15.這就是公式中sqrt(15)項的原因。

統計分析: 要驗證所有上述假設和近似值是否合理,我們進行一些統計分析。

首先,讓我們檢查分佈:

figure; 
xGrid = (-15 : 0.1 : 15); 
histogram(real(Result(:)), xGrid, 'Normalization','pdf', 'EdgeColor', 'None'); 
hold on; 
plot(xGrid, normpdf(xGrid, 0, sqrt(15)), 'r', 'LineWidth', 2); 
legend({'Simulated histogram', 'Gaussian pdf'}); 
title('Distribution of the real term'); 

enter image description here

虛數項(這裏沒有顯示)的直方圖看起來也相同。該測試驗證具有零均值和15個方差的高斯分佈的假設。

最後,讓我們檢查一下真實和虛擬術語之間的獨立性。

covar = cov(real(Result(:)), imag(Result(:))); 
disp(covar); 
% 14.9968 0.0036 
% 0.0036 14.9936  

兩件事情可以注意到:(1)如前所述,每個的實數和虛數項的方差爲約15。(2)相比,該實數和虛數項之間的協方差是小得多個體差異。這支持了他們獨立的論點。

+1

+1有趣的答案。在R2016b中,擺脫'for'循環的第一種方法比較慢了20%左右。矢量化並不總是贏。 – horchler

+0

也可考慮使用不同的[基數隨機數生成方案](https://www.mathworks.com/help/matlab/ref/randstream.list.html),以獲得更快的速度,例如''dsfmt19937''或' 'shr3cong'':'s = RandStream('dsfmt19937','Seed',1);''randn(s,200,50,300)'。 – horchler

+0

@horchler:我已將您的建議納入我的答案。謝謝! – aksadv