我有两个向量,我正在尝试在一定的容差范围内找出一个在另一个上的所有重合,而不是使用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]
我做错了什么?有没有其他解决方案?
2条答案
按热度按时间ubof19bj1#
您的问题是,在代码的当前状态下,
ismembertol
只为在A中找到的B的每个元素输出一个索引,因此当一个元素在容差范围内被多次找到时,您会丢失信息。根据文档,您可以使用
'OutputAllIndices',true
值对参数语法,只需调用ismembertol
即可在ia
中输出所需内容:celldisp(ia) % tol = 0
celldisp(ia) % tol = 1
yeotifhr2#
这里是一种手动方法,只是为了提供另一种方法。它计算所有绝对差异的中间矩阵(使用隐式展开),并根据小于公差的条目的行和列索引构建结果:
请注意,此方法
ismembertol
,所以可以在老版本的MatLab中使用,但隐式扩展需要显式调用bsxfun
: