我有兩個向量,我試圖在不使用 for 回圈的情況下,在一定的容差范圍內找到另一個向量的所有重合。容差是指,例如,如果我有數字 3,容差為 2,我希望將值保持在 3±2 以內,因此 (1,2,3,4,5)。
A = [5 3 4 2]; B = [2 4 4 4 6 8];
我想獲得一個單元格陣列,其中每個單元格上包含所有重合的數量,公差為 1 個(或更多)單位。(A = B - 1) 我有一個零單位 (A = B) 的解決方案,它看起來像這樣:
tol = 0;
[tf, ia] = ismembertol(B,A,tol,'DataScale',1); % For tol = 0, this is equivalent to using ismember
idx = 1:numel(B);
ib = accumarray(nonzeros(ia), idx(tf), [], @(x){x}) % This gives the cell array
輸出是:
ib =
[]
[]
[2 3 4]
[1]
這是所希望的。如果我將容差更改為 1,則代碼無法按預期作業。它改為輸出:
tol = 1
[tf, ia] = ismembertol(B,A,tol,'DataScale',1); % For tolerance = 1, this is equivalent to using ismember
idx = 1:numel(B);
ib = accumarray(nonzeros(ia), idx(tf), [], @(x){x}) % This gives the cell array
ib =
[5]
[2 3 4]
[]
[1]
當我期望獲得:
ib =
[2 3 4 5]
[1 2 3 4]
[2 3 4]
[1]
我究竟做錯了什么?有替代解決方案嗎?
uj5u.com熱心網友回復:
您的問題是,在代碼的當前狀態下,ismembertol在 A 中找到的 B 的每個元素僅輸出 1 個索引,因此在可以在容差范圍內多次找到元素的情況下,您會丟失資訊。
根據檔案,您可以使用值對引數語法,只需呼叫以下命令'OutputAllIndices',true即可輸出您想要的內容:iaismembertol
A = [5 3 4 2]; B = [2 4 4 4 6 8];
tol = 0;
[tf, ia] = ismembertol(A,B,tol,'DataScale',1,'OutputAllIndices',true);
celldisp(ia) % tol = 0
ia{1} = 0 ia{2} = 0 ia{3} = 2 3 4 ia{4} = 1
celldisp(ia) % tol = 1
ia{1} = 2 3 4 5 ia{2} = 1 2 3 4 ia{3} = 2 3 4 ia{4} = 1
uj5u.com熱心網友回復:
這里是手動的方法,只是為了提供另一種方法。它計算所有絕對差的中間矩陣(使用隱式擴展),并根據小于容差的條目的行和列索引構建結果:
A = [5 3 4 2];
B = [2 4 4 4 6 8];
tol = 1;
[ii, jj] = find(abs(A(:).'-B(:))<=tol);
ib = accumarray(jj, ii, [numel(A) 1], @(x){x});
請注意,這種方法
- 由于中間矩陣,可能是記憶體密集型的;
- 可以在舊的 Matlab 版本中作業,因為它不使用
ismembertol; 但是隱式擴展必須通過顯式呼叫來替換bsxfun:
[ii, jj] = find(abs(bsxfun(@minus, A(:).', B(:)))<=tol);
ib = accumarray(jj, ii, [numel(A) 1], @(x){x});
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/526300.html
標籤:数组matlab片
