訪問多維結構的數據是在MATLAB中出了名的慢,所以將您的數據到一個普通的數組有一定的幫助:
kk = 1;
DoubleMatches = Matches1;
%// transform to regular array
Matches1queryIdx = [Matches1.queryIdx];
Matches1trainIdx = [Matches1.trainIdx];
Matches2queryIdx = [Matches2.queryIdx];
Matches2trainIdx = [Matches2.trainIdx];
%// loop through transformed data instead of structures
for ii = 1:length(Matches1queryIdx)
for jj = 1:length(Matches1queryIdx)
if((Matches1queryIdx(ii)==Matches2trainIdx(jj)) && ...
(Matches1trainIdx(ii)==Matches2queryIdx(jj)))
DoubleMatches(kk) = Matches1(ii);
kk = kk+1;
end
end
end
DoubleMatches(kk:end)=[];
還有,其幾乎完全矢量化的解決方案:
matches = sum(...
bsxfun(@eq, [Matches1.queryIdx], [Matches2.trainIdx].') & ...
bsxfun(@eq, [Matches1.trainIdx], [Matches2.queryIdx].'));
contents = arrayfun(@(x)..
repmat(Matches1(x),1,matches(x)), 1:numel(matches), ...
'Uniformoutput', false);
DoubleMatches2 = [contents{:}]';
注意,這可能是很多更多的內存密集型(它有O(N²)峯值內存佔用,而不是O(N)爲其他,儘管峯值內存的數據類型爲logical
,因此小於double
...)。最好事先檢查一下你應該使用哪一個。
稍微測試一下。我用下面的僞數據:
Matches1 = struct(...
'queryIdx', num2cell(randi(25,1000,1)),...
'trainIdx', num2cell(randi(25,1000,1))...
);
Matches2 = struct(...
'queryIdx', num2cell(randi(25,1000,1)),...
'trainIdx', num2cell(randi(25,1000,1))...
);
和以下測試:
%// Your original method
tic
kk = 1;
DoubleMatches = Matches1;
for ii = 1:length(Matches1)
for jj = 1:length(Matches2)
if((Matches1(ii).queryIdx==Matches2(jj).trainIdx) && ...
(Matches1(ii).trainIdx==Matches2(jj).queryIdx))
DoubleMatches(kk) = Matches1(ii);
kk = kk+1;
end
end
end
DoubleMatches(kk:end)=[];
toc
DoubleMatches1 = DoubleMatches;
%// Method with data transformed into regular array
tic
kk = 1;
DoubleMatches = Matches1;
Matches1queryIdx = [Matches1.queryIdx];
Matches1trainIdx = [Matches1.trainIdx];
Matches2queryIdx = [Matches2.queryIdx];
Matches2trainIdx = [Matches2.trainIdx];
for ii = 1:length(Matches1queryIdx)
for jj = 1:length(Matches1queryIdx)
if((Matches1queryIdx(ii)==Matches2trainIdx(jj)) && ...
(Matches1trainIdx(ii)==Matches2queryIdx(jj)))
DoubleMatches(kk) = Matches1(ii);
kk = kk+1;
end
end
end
DoubleMatches(kk:end)=[];
toc
DoubleMatches2 = DoubleMatches;
% // Vectorized method
tic
matches = sum(...
bsxfun(@eq, [Matches1.queryIdx], [Matches2.trainIdx].') & ...
bsxfun(@eq, [Matches1.trainIdx], [Matches2.queryIdx].'));
contents = arrayfun(@(x)repmat(Matches1(x),1,matches(x)), 1:numel(matches), 'Uniformoutput', false);
DoubleMatches3 = [contents{:}]';
toc
%// Check if all are equal
isequal(DoubleMatches1,DoubleMatches2, DoubleMatches3)
結果:
Elapsed time is 6.350679 seconds. %// ( 1×) original method
Elapsed time is 0.636479 seconds. %// (~10×) method with regular array
Elapsed time is 0.165935 seconds. %// (~40×) vectorized
ans =
1 %// indeed, outcomes are equal
'Matches1'是什麼類型的東西?你定義的類的一個對象?我不明白'Matches1(i).queryIdx'的語法是否正確...(但是我從來沒有在Matlab中使用過類,所以可能是問題) –
這實際上是一個很好的問題;我會用這個作爲一個模範問題來引用其他人,如果這對你很好? –
@reverse_engineer:嗨,MatchesX是結構,這是與各種元素(因此匹配(我))和各元素的不同字段(其中之一是.queryIdx)的各種值的結構。 – McMa