2017-09-07 228 views
7

在R2015a中引入的uniquetol函數計算「容差範圍內的獨特元素」。具體而言,「uniquetol」究竟做了什麼?

C = uniquetol(A,tol)返回使用公差tolA獨特的元件。

但是找到具有給定容差的獨特元素的問題有幾種解決方案。哪一個是實際生產的?

讓我們看兩個例子:

  1. A = [3 5 7 9]絕對寬容2.5。輸出可以是[3 7],也可以是[5 9]。兩種解決方案都滿足要求。

  2. 對於A = [1 3 5 7 9]與絕對公差2.5,輸出可以是[1 5 9][3 7]。所以即使輸出中的元素的號碼也可以變化。

請參閱this nice discussion瞭解位於問題核心的傳遞性問題。

那麼,uniquetol是如何工作的?它在幾種現有解決方案中產生了什麼輸出?

+0

爲什麼'反向engineering'標籤? – arrowd

+0

@arrowd,因爲他反向工程的作用 –

+0

@arrowd說實話,我並不完全確定它適用於此。我認爲它的確如描述所說_逆向工程是通過分析其功能和操作來發現人造物體或系統的技術原理的過程._ –

回答

7

爲了簡化,我考慮一輸出,雙輸入版本的uniquetol

C = uniquetol(A, tol); 

其中第一輸入是double矢量A。特別是,這意味着:

  • uniquetol'ByRows'選項未被使用。
  • 第一個輸入是一個向量。如果不是,像往常一樣,uniquetol會隱式線性化爲一列。
  • 第二輸入,它定義了公差,被解釋as follows

    兩個值,uv,是容差範圍內,如果abs(u-v) <= tol*max(abs(A(:)))

    即,在規定的公差是相對默認爲。在比較中使用的實際公差通過的比例獲得A的最大絕對值。

考慮到這些因素,似乎uniquetol使用方法是:

  1. 排序A
  2. 挑選排序的A的第一個條目,並將其設置爲參考值(此值將稍後更新)。
  3. 將參考值寫入輸出C
  4. 跳過排序的A的後續條目,直到找到一個不在參考值的容差範圍內的條目。當該條目被發現,把它作爲新的參考值,並返回到第3步。

當然,我並不是說這是什麼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 

在我所有的測試中,這個運行沒有斷言失敗。

所以,摘要uniquetol似乎排序的輸入,其挑選第一個條目,並保持跳躍項,只要它可以

對於問題中的兩個例子,輸出結果如下。需要注意的是第二個輸入被指定爲2.5/9,其中9是最大的第一輸入,實現2.5絕對公差:

>> uniquetol([1 3 5 7 9], 2.5/9) 
ans = 
    1  5  9 
>> uniquetol([3 5 7 9], 2.5/9) 
ans = 
    3  7 
+1

因此,對於問題中的例子,這是輸出? (+1) –

+1

@AnderBiguri好點,我會包括這一點。它基本上選取它找到的第一個值,然後跳過值直到它不能跳過。所以:'uniquetol([3 5 7 9],2.5/9)'給出'[3 7]'; 'uniquetol([1 3 5 7 9],2.5/9)'給出'[1 5 9]'。注意所需的'/ 9'因此'2.5'是_absolute_容差 –