R2015a中引入的uniquetol函数计算“公差范围内的唯一元素”明确地,
C = uniquetol(A,tol)使用toleranceA返回tol中的唯一元素。
但是找到具有给定公差的唯一元素的问题有几个解决方案哪一个是实际生产的?
让我们看两个例子:
设绝对公差A = [3 5 7 9]输出可以是2.5,也可以是[3 7]两种方案均满足要求。
对于绝对公差[5 9]A = [1 3 5 7 9],输出可以是2.5[1 5 9]因此,即使输出中的元素数量也可能有所不同。
关于问题核心的及物性问题,请参见this nice discussion
那么,[3 7]是如何工作的呢它在多个现有解决方案中产生了什么输出?

最佳答案

为了简化,我考虑一个输出,两个输入版本的uniquetol

 C = uniquetol(A, tol);

其中第一个输入是向量特别是,这意味着:
未使用double选项。
第一个输入是向量如果不是这样,A会像往常一样隐式地线性化到列。
定义公差的第二个输入被解释为:
如果'ByRows'
也就是说,默认情况下指定的公差是相对的在比较中使用的实际公差是通过在uniquetol中的最大绝对值缩放得到的。
考虑到这些因素,uniquetol使用的方法似乎是:
排序u
选择sortedv的第一个条目,并将其设置为参考值(该值稍后必须更新)。
将参考值写入输出abs(u-v) <= tol*max(abs(A(:)))
跳过已排序A的后续条目,直到找到不在参考值公差范围内的条目找到该条目后,将其作为新的参考值并返回到步骤3。
当然,我不是说这就是uniquetol内部所做的但产出似乎是一样的所以这在功能上等同于A的作用。
下面的代码实现了上面描述的方法(低效的代码,只是为了说明这一点)。
% 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

为了验证这一点,让我们生成一些随机数据并比较A和上面代码的输出:
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

在我所有的测试中,这个断言都没有失败。
因此,总而言之,C似乎对输入进行排序,选择其第一个条目,并尽可能长时间地跳过条目。
对于问题中的两个示例,输出如下注意,第二个输入被指定为A,其中uniquetol是第一个输入的最大值,以达到uniquetol的绝对容忍度:
>> uniquetol([1 3 5 7 9], 2.5/9)
ans =
     1     5     9
>> uniquetol([3 5 7 9], 2.5/9)
ans =
     3     7

09-25 16:20