“uniquetol”究竟做了什么?

时间:2017-09-07 16:32:21

标签: arrays matlab unique reverse-engineering

R2015a中引入的uniquetol函数计算“容差范围内的独特元素”。具体地,

  

C = uniquetol(A,tol)使用容差A返回tol中的唯一元素。

但是,找到具有给定容差的独特元素的问题有几个解决方案。实际生产哪一个?

让我们看两个例子:

  1. A = [3 5 7 9]具有绝对容差2.5。输出可以是[3 7],也可以是[5 9]。两种解决方案都满足要求。

  2. 对于具有绝对容差A = [1 3 5 7 9]的{​​{1}},输出可以是2.5[1 5 9]。因此,即使输出中元素的数量也可能不同。

  3. 请参阅this nice discussion有关问题核心的传递性问题。

    那么[3 7]如何运作?它在几个现有解决方案中产生了什么输出?

1 个答案:

答案 0 :(得分:7)

简化,我会考虑{em>单输出,双输入版uniquetol

 C = uniquetol(A, tol);

其中第一个输入是double 向量 A。特别是,这意味着:

  • 未使用'ByRows'的{​​{1}}选项。
  • 第一个输入是矢量。如果不是,uniquetol将像往常一样隐式线性化为列。
  • 定义容差的第二个输入被解释为as follows

      

    如果uniquetol

    ,则uv这两个值都在容差范围内

    也就是说,默认情况下,指定的容差是 relative 。比较中使用的实际容差是通过缩放获得abs(u-v) <= tol*max(abs(A(:)))中的最大绝对值来获得的。

考虑到这些因素,A使用的方法似乎是:

  1. 排序uniquetol
  2. 选择排序A的第一个条目,并将其设置为参考值(此值必须稍后更新)。
  3. 将参考值写入输出A
  4. 跳过排序C的后续条目,直到找到一个不在参考值容差范围内的条目。找到该条目后,将其作为新的参考值并返回步骤3.
  5. 当然,我并不是说这就是A 内部所做的事情。但输出似乎是一样的。因此,功能等同于uniquetol所做的。

    以下代码可能更清晰(效率低下的代码,只是为了说明这一点)

    uniquetol

    验证,请让我们生成一些随机数据并比较% Inputs A, tol % Output C tol_scaled = tol*max(abs(A(:))); % scale tolerance C = []; % initiallize output. Will be extended ref = NaN; % initiallize reference value to NaN. This will immediately cause % A(1) to become the new reference for a = sort(A(:)).'; if ~(a-ref <= tol_scaled) ref = a; C(end+1) = ref; end end 和上述代码的输出:

    uniquetol

    在我的所有测试中,这都没有断言失败。

    因此,在摘要中,clear N = 1e3; % number of realizations S = 1e5; % maximum input size for n = 1:N; % Generate inputs: s = randi(S); % input size A = (2*rand(1,S)-1) / rand; % random input of length S; positive and % negative values; random scaling tol = .1*rand; % random tolerance (relative). Change value .1 as desired % Compute output: tol_scaled = tol*max(abs(A(:))); % scale tolerance C = []; % initiallize output. Will be extended ref = NaN; % initiallize reference value to NaN. This will immediately cause % A(1) to become the new reference for a = sort(A(:)).'; if ~(a-ref <= tol_scaled) ref = a; C(end+1) = ref; end end % Check if output is equal to that of uniquetol: assert(isequal(C, uniquetol(A, tol))) end 似乎对输入进行排序,选择其第一个条目,继续跳过条目。< / p>

    对于问题中的两个例子,输出如下。请注意,第二个输入指定为uniquetol,其中2.5/9是第一个输入的最大值,以实现9的绝对容差:

    2.5