我有下面的代碼需要計算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
任何幫助,將不勝感激。 在此先感謝。
我有下面的代碼需要計算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
任何幫助,將不勝感激。 在此先感謝。
首先,我不認爲這個計算順序可以做得更快。下面可能是一個很小的有點快,但肯定不是由量你正在尋找:
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的時序結果,如下:
也可以嘗試其他隨機數生成方案,例如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');
虛數項(這裏沒有顯示)的直方圖看起來也相同。該測試驗證具有零均值和15個方差的高斯分佈的假設。
最後,讓我們檢查一下真實和虛擬術語之間的獨立性。
covar = cov(real(Result(:)), imag(Result(:)));
disp(covar);
% 14.9968 0.0036
% 0.0036 14.9936
兩件事情可以注意到:(1)如前所述,每個的實數和虛數項的方差爲約15。(2)相比,該實數和虛數項之間的協方差是小得多個體差異。這支持了他們獨立的論點。
+1有趣的答案。在R2016b中,擺脫'for'循環的第一種方法比較慢了20%左右。矢量化並不總是贏。 – horchler
也可考慮使用不同的[基數隨機數生成方案](https://www.mathworks.com/help/matlab/ref/randstream.list.html),以獲得更快的速度,例如''dsfmt19937''或' 'shr3cong'':'s = RandStream('dsfmt19937','Seed',1);''randn(s,200,50,300)'。 – horchler
@horchler:我已將您的建議納入我的答案。謝謝! – aksadv
你是否介紹了該代碼?在那種情況下,'exp'與其他行相比有多少時間?也許問題不在'exp'中。 – mpaskov
我懷疑這將是更快的矢量化。內存消耗本身就會很大。對於涉及大內存的計算,'for'循環更好。 – rayryeng
在你的代碼中,'i'與'1i'不一樣。我希望你已經知道了! –