非循环查找两向量容差匹配:ismembertol问题及替代方案
错误原因
ismembertol的设计逻辑是为B中的每个元素匹配A中第一个满足容差条件的元素,而非找出A中每个元素对应的所有B中符合条件的元素。当容差为1时:
- B的第5个元素6,只会匹配A中第一个满足
|6 - A(i)| ≤1的元素(即A(1)=5),因此ia中对应位置标记为1; - B的第1个元素2,只会匹配A中第一个满足
|2 - A(i)| ≤1的元素(即A(4)=2),因此ia中对应位置标记为4; - 但A(1)=5对应的B中元素(4、4、4、6,索引2-5)、A(2)=3对应的B中元素(2、4、4、4,索引1-4)这些匹配关系,因
ismembertol的单一匹配逻辑被遗漏,最终导致元胞数组不符合预期。
替代解决方案
利用矩阵广播生成所有元素的差值矩阵,筛选符合容差的位置后,通过accumarray生成目标元胞数组,全程无需for循环:
A = [5 3 4 2]; B = [2 4 4 4 6 8]; tol = 1; % 生成差值矩阵,判断每个A元素与B元素是否满足容差 match_matrix = abs(B' - A) <= tol; % 收集每个A元素对应的B索引并生成元胞数组 [rows, cols] = find(match_matrix); ib = accumarray(cols, rows, [], @(x){sort(x)});
运行后输出与预期完全一致:
ib = [2 3 4 5] [1 2 3 4] [2 3 4] [1]
方案说明
B' - A通过广播生成6×4的差值矩阵,每个元素对应B(j) - A(i);abs(...) <= tol生成逻辑矩阵,标记所有满足容差的位置;find(match_matrix)提取所有符合条件的B索引(行)和对应的A索引(列);accumarray按A的索引分组,收集对应的B索引并排序,最终生成目标元胞数组。
内容的提问来源于stack exchange,提问作者haveaniceafterlife
相关产品推荐
相关产品推荐

