你的for循環其實很快。
正如@EBH在評論中提到的,您的代碼應該在最新的2016版本中運行,但由於我使用的是早期的2015版本,因此不支持隱式擴展。
原始聲明:rangesearch(A,A,0.01)
並不保證您可以爲每個點獲取單個鄰居。事實上,當我與N=10
運行,那麼ID總是{1 2 3 4 5 6 7 8 9 10}
固定的循環方法:
tic
result = zeros(N,1);
for i = 1:N
idx = id{i}';
v1 = bsxfun(@minus, A(i,:), A(idx,:));
v2 = bsxfun(@minus, A(i,:), B(idx,:));
C = cross(v1,v2,2);
D = sqrt(sum(C.^2,2))./Dist(idx);
result(i) = sum(2 * sqrt(R^2 - D.^2));
end
toc
Elapsed time is 0.077025 seconds.
方法2:枚舉v1和v2
tic
idlen = cellfun(@(x) length(x),id);
idai = cell2mat(arrayfun(@(ii) repmat(ii,1,idlen(ii)), (1:N), 'UniformOutput', false));
idx2 = cell2mat(id');
V1 = A(idai,:) - A(idx2,:);
V2 = A(idai,:) - B(idx2,:);
C2 = cross(V1,V2,2);
d = @(c,id) sqrt(sum(c.^2,2))./Dist(id);
r = @(d) sum(2 * sqrt(R^2 - d.^2));
result3 = splitapply(@(c,id) r(d(c,id)), C2,idx2', idai');
toc
isequal(result,result3)
Elapsed time is 0.471092 seconds.
ans =
1
之間所有可能的組合最慢的線是splitapply
方法3:使用cellfun
,這並不能保證矢量
tic
V1 = cellfun(@(Ai,idx) bsxfun(@minus, Ai, A(idx,:)), num2cell(A,2), id, 'UniformOutput', false);
V2 = cellfun(@(Ai,idx) bsxfun(@minus, Ai, B(idx,:)), num2cell(A,2), id, 'UniformOutput', false);
C = cellfun(@(v1,v2) cross(v1,v2,2), V1,V2, 'UniformOutput', false);
D = cellfun(@(c,idx) sqrt(sum(c.^2,2))./Dist(idx), C, id, 'UniformOutput', false);
result2 = cellfun(@(d) sum(2 * sqrt(R^2 - d.^2)), D, 'UniformOutput', false);
result2 = cell2mat(result2);
toc
isequal(result,result2)
Elapsed time is 0.122700 seconds.
ans =
1
方法4:使用parfor
tic
result = zeros(N,1);
parfor i = 1:N
idx = id{i}';
v1 = bsxfun(@minus, A(i,:), A(idx,:));
v2 = bsxfun(@minus, A(i,:), B(idx,:));
C = cross(v1,v2,2);
D = sqrt(sum(C.^2,2))./Dist(idx);
result(i) = sum(2 * sqrt(R^2 - D.^2));
end
toc
Elapsed time is 0.177929 seconds.
parfor
抱怨A
,B
和Dist
不能切片,與減慢計算速度。
編輯:上述測試使用N=1000
。如果我使用N=10000
則方法2的時間減少40%,方法3的消耗時間相同,方法4的時間減少約90%。所以,如果你使用的是多核計算機,那麼你可以去parfor
。
這不是一個錯誤,它是2016b [隱式廣播實現](https://www.mathworks.com/help/matlab/release-notes.html?rntext=bsxfun&startrelease=R2016b&endrelease=R2016b&groupby=release&sortby=descending&searchHighlight=) – EBH
此外,['timeit'](http://www.mathworks.com/help/releases/R2016b/matlab/ref/timeit.html)在測量功能運行時間方面更加準確。 – EBH
@EBH哈我還在2015年。 – Yvon