Main Content

uniquetol

容差内的唯一值

说明

示例

C = uniquetol(A,tol) 使用容差 tol 返回 A 中的唯一元素。满足以下条件时,uv 这两个值位于容差范围内

abs(u-v) <= tol*max(abs(A(:)))

即,uniquetol 基于数据量级调整 tol 输入。

uniquetol 类似于 unique。而 unique 执行精确比较,uniquetol 使用容差执行比较。

示例

C = uniquetol(A) 对单精度输入使用默认容差 1e-6,对双精度输入使用默认容差 1e-12

C = uniquetol(A,tol,occurrence)(其中 occurrence'highest')指定当几个值在彼此的容差范围内时,应选取最高值作为唯一元素。occurrence 的默认值为 'lowest',它会选取最小值作为唯一元素。

示例

[C,IA,IC] = uniquetol(___) 返回索引向量 IAIC,满足 C = A(IA)A~C(IC)(或者 A(:)~C(IC),如果 A 为矩阵),其中 ~ 意味着各个值均处于彼此的容差范围内。您可以使用上述语法中的任何输入参量。

示例

[___] = uniquetol(___,Name,Value) 使用一个或多个名称-值对组指定的其他选项,这些选项使用上述语法中的任意输入或输出参量组合。例如,uniquetol(A,'ByRows',true) 确定 A 中的唯一行。

示例

全部折叠

创建向量 x。通过变换和取消变换 x 来获取第二个向量 y。此变换会向 y 中引入舍入误差。

x = (1:6)'*pi;
y = 10.^log10(x);

通过取差值来验证 xy 不同。

x-y
ans = 6×1
10-14 ×

    0.0444
         0
         0
         0
         0
   -0.3553

使用 unique 找出串联向量 [x;y] 中的唯一元素。unique 函数执行精确比较,并确定 x 中有些值与 y 中的值不完全相等。这些值与那些在 x-y 中具有非零差分的元素是同一批元素。因此,c 中包含一些貌似重复的值(实际上有细微差异)。

c = unique([x;y])
c = 8×1

    3.1416
    3.1416
    6.2832
    9.4248
   12.5664
   15.7080
   18.8496
   18.8496

使用 uniquetol 应用一个较小的容差执行比较。uniquetol 会将处于容差范围内的元素视为相等。

C = uniquetol([x;y])
C = 6×1

    3.1416
    6.2832
    9.4248
   12.5664
   15.7080
   18.8496

默认情况下,uniquetol 查找处于容差范围内的唯一元素,但它也可以查找矩阵中处于容差范围内的唯一

创建一个数值矩阵 A。通过变换和取消变换 A 来获取第二个矩阵 B。此变换会向 B 引入舍入差异。

A = [0.05 0.11 0.18; 0.18 0.21 0.29; 0.34 0.36 0.41; 0.46 0.52 0.76];
B = log10(10.^A);

使用 unique 找出 AB 中的唯一行。unique 函数执行精确比较,并确定串联矩阵 [A;B] 中的所有行都是唯一的,即使一些行仅有非常小的差别。

unique([A;B],'rows')
ans = 8×3

    0.0500    0.1100    0.1800
    0.0500    0.1100    0.1800
    0.1800    0.2100    0.2900
    0.1800    0.2100    0.2900
    0.3400    0.3600    0.4100
    0.3400    0.3600    0.4100
    0.4600    0.5200    0.7600
    0.4600    0.5200    0.7600

使用 uniquetol 找出唯一行。uniquetol 将处于容差范围内的行视为相等。

uniquetol([A;B],'ByRows',true)
ans = 4×3

    0.0500    0.1100    0.1800
    0.1800    0.2100    0.2900
    0.3400    0.3600    0.4100
    0.4600    0.5200    0.7600

创建向量 x。通过变换和取消变换 x 来获取第二个向量 y。此变换会向 y 中的一些元素引入舍入误差。

x = (1:5)'*pi;
y = 10.^log10(x);

xy 合并为单个向量 A。使用 uniquetol 重新构造 A,并将处于容差范围内的值视为相等。

A = [x;y]
A = 10×1

    3.1416
    6.2832
    9.4248
   12.5664
   15.7080
    3.1416
    6.2832
    9.4248
   12.5664
   15.7080

[C,IA,IC] = uniquetol(A);
newA = C(IC)
newA = 10×1

    3.1416
    6.2832
    9.4248
   12.5664
   15.7080
    3.1416
    6.2832
    9.4248
   12.5664
   15.7080

您可以在后续代码中将 newA== 或验证全等的函数结合使用,如 isequalunique

D1 = unique(A)
D1 = 6×1

    3.1416
    3.1416
    6.2832
    9.4248
   12.5664
   15.7080

D2 = unique(newA)
D2 = 5×1

    3.1416
    6.2832
    9.4248
   12.5664
   15.7080

使用 occurrence 选项控制 uniquetol 选取哪些元素作为唯一元素。

创建一个向量,并找出在 1e-1 的容差范围内哪些元素是唯一元素。

a = [1 1.1 1.11 1.12 1.13 2];
c = uniquetol(a,1e-1)
c = 1×2

     1     2

由于 A 中的前五个元素都具有关于 1e-1 的容差的相似值,因此只有其中的最小值被选取为唯一元素。这是因为 uniquetola 中的最小值开始,直到到达向量末尾的 2 才找到不在容差范围内的新元素。

使用 'highest' 选项指定 uniquetol 应从 a 中的最高值开始。1.13 元素被选作唯一元素,因为 uniquetol 从最高值向下查找。

d = uniquetol(a,1e-1,'highest')
d = 1×2

    1.1300    2.0000

创建一个由二维样本点组成的云,这些样本点限定在一个以点 (12,12) 为圆心,以 0.5 为半径的圆内。

x = rand(10000,2); 
insideCircle = sqrt((x(:,1)-.5).^2+(x(:,2)-.5).^2)<0.5;
y = x(insideCircle,:);

求解一个缩小的点集,以便原始数据集中的每个点都处于该点集中点的容差范围之内。

tol = 0.05;
C = uniquetol(y,tol,'ByRows',true);

在原始数据集之上以红点的形式绘制缩小的点集。所有红点都是原始数据集的成员。所有红点之间的距离至少为 tol

plot(y(:,1),y(:,2),'.')
hold on
axis equal
plot(C(:,1), C(:,2), '.r', 'MarkerSize', 10)

创建一个随机数向量,并使用容差确定唯一元素。将 OutputAllIndices 指定为 true,以返回处于唯一值的容差范围内的元素的所有索引。

A = rand(100,1);
[C,IA] = uniquetol(A,1e-2,'OutputAllIndices',true);

计算处于值 C(2) 的容差范围内的元素的平均值。

C(2)
ans = 0.0318
allA = A(IA{2})
allA = 3×1

    0.0357
    0.0318
    0.0344

aveA = mean(allA)
aveA = 0.0340

默认情况下,uniquetol 使用 abs(u-v) <= tol*DS 形式的容差测试,其中 DS 会根据输入数据的量级自动缩放。您可以另外指定 DS 值以用于 DataScale 选项。但是,绝对容差(其中 DS 为标量)不会根据输入数据的量级缩放。

首先,比较相距 eps 的两个较小值。指定 tolDS 以生成满足容差范围的等式:abs(u-v) <= 10^-6

x = 0.1;
uniquetol([x, exp(log(x))], 10^-6, 'DataScale', 1)
ans = 0.1000

接下来,增大这些值的量级。exp(log(x)) 计算中的舍入误差与这些值的量级成正比,具体来说,是 eps(x)。即使两个较大值彼此相距 epseps(x) 现在也更大。因此,10^-6 不再是适合的容差。

x = 10^10;
uniquetol([x, exp(log(x))], 10^-6, 'DataScale', 1)
ans = 1×2
1010 ×

    1.0000    1.0000

使用 DS 的默认(缩放)值可更正此问题。

format long
Y = [0.1 10^10];
uniquetol([Y, exp(log(Y))])
ans = 1×2
1010 ×

   0.000000000010000   1.000000000000000

创建一个随机二维点集,然后使用 uniquetol 将这些点分组到具有相似 x 坐标(容差范围之内)的垂直波段中。将以下选项与 uniquetol 配合使用:

  • ByRows 指定为 true,因为点坐标在 A 的行中。

  • OutputAllIndices 指定为 true,以返回那些 x 坐标在彼此容差范围内的所有点的索引。

  • DataScale 指定为 [1 Inf],以将绝对容差用于 x 坐标,同时忽略 y 坐标。

A = rand(1000,2);
DS = [1 Inf];
[C,IA] = uniquetol(A, 0.1, 'ByRows', true, ...
    'OutputAllIndices', true, 'DataScale', DS);

绘制每个波段的点和平均值。

hold on
for k = 1:length(IA)
    plot(A(IA{k},1), A(IA{k},2), '.')
    meanAi = mean(A(IA{k},:));
    plot(meanAi(1), meanAi(2), 'xr')
end

输入参数

全部折叠

查询数组,指定为标量、向量、矩阵或多维数组。A 必须为满矩阵。

数据类型: single | double

比较容差,指定为正实数标量。uniquetol 使用输入数组 A 中的最大绝对值缩放 tol 输入。uniquetol 使用生成的缩放比较容差确定 A 中的哪些元素是唯一的。如果 A 中的两个元素处于彼此容差范围之内,则 uniquetol 将它们视为相等。

如果 abs(u-v) <= tol*max(abs(A)),则 uv 这两个值在容差范围内。

要指定绝对容差,请同时指定 tol'DataScale' 名称-值对组。

示例: tol = 0.05

示例: tol = 1e-8

示例: tol = eps

数据类型: single | double

唯一值的选取方式,指定为下表中的选项之一。occurrence 的值确定 uniquetol 选取哪些元素作为唯一元素。

选项描述
'lowest'

uniquetolA 中的最小值开始,然后重复查找 A 中下一个最小值,此最小值需不在 C 中任何其他值的容差范围内。这样做的效果是,当几个输入值在彼此的容差范围内时,会选取该最小值作为唯一元素。

'highest'

uniquetolA 中的最高值开始,然后重复查找 A 中下一个最大值,此最大值需不在 C 中任何其他值的容差范围内。这样做的效果是,当几个输入值在彼此的容差范围内时,会选取该最高值作为唯一元素。

示例: C = uniquetol(A,tol,'highest')

示例: C = uniquetol([1 2 3],2,'highest') 返回 3,因为 uniquetol 从输入中的最高值开始,所有其他值都在容差范围内。

数据类型: char | string

名称-值参数

将可选的参量对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参量名称,Value 是对应的值。名称-值参量必须出现在其他参量之后,但参量对组的顺序无关紧要。

在 R2021a 之前,使用逗号分隔每个名称和值,并用引号将 Name 引起来。

示例: C = uniquetol(A,'ByRows',true)

输出索引类型,指定为包含 'OutputAllIndices' 以及 false(默认值)、true01 的逗号分隔对组。uniquetol 将数值 0 解释为 false,将数值 1 解释为 true

OutputAllIndicestrue 时,uniquetol 函数会以元胞数组形式返回第二个输出 IA。该元胞数组包含 A 中处于 C 中值的容差范围内的所有元素的索引。即,IA 中的每个元胞对应于 C 中的一个值,每个元胞中的值对应于 A 中的位置。

示例: [C,IA] = uniquetol(A,tol,'OutputAllIndices',true)

行比较切换,指定为包含 'ByRows' 以及 false(默认值)、true01 的逗号分隔对组。uniquetol 将数值 0 解释为 false,将数值 1 解释为 true。使用此选项可查找 A 中处于容差范围内的行。

ByRowstrue 时:

  • A 必须为二维数组。

  • uniquetol 通过分别考虑每一列来比较 A 的行。要使两行处于彼此的容差范围内,则每一列都必须处于容差范围内。

  • A 中的每行都处于 C 中的行的容差范围内。但是,C 中的任意两行都不在彼此的容差范围内。

如果 all(abs(u-v) <= tol*max(abs(A),[],1)),则 uv 这两行在容差范围内。

示例: C = uniquetol(A,tol,'ByRows',true)

数据缩放,指定为包含 'DataScale' 以及标量或向量的逗号分隔对组。将 DataScale 指定为数值标量 DS,以将容差检验更改为 abs(u-v) <= tol*DS

ByRows 选项一起使用时,DataScale 值还可以是向量。在本例中,该向量的每个元素指定 A 中对应列的 DS。如果 DataScale 向量中的某个值为 Inf,则 uniquetol 将忽略 A 中的对应列。

示例: C = uniquetol(A,'DataScale',1)

示例: [C,IA,IC] = uniquetol(A,'ByRows',true,'DataScale',[eps(1) eps(10) eps(100)])

数据类型: single | double

范围保留切换,指定为包含 'PreserveRange' 以及 false(默认值)、true01 的逗号分隔对组。uniquetol 将数值 0 解释为 false,将数值 1 解释为 true。使用此选项指定输出 C 中的最小值和最大值应与 A 中的最小值和最大值相同。

如果 A 中的最小值和最大值在彼此的容差 tol 内,则 uniquetol 仅返回其中一个值。

示例: C = uniquetol(A,tol,'PreserveRange',true)

输出参量

全部折叠

A 中的唯一元素(处于容差范围内),以向量或矩阵的形式返回。如果 A 是行向量,则 C 也是行向量。否则,C 为列向量。C 中的元素以升序排序。A 中的每个元素都处于 C 中的元素的容差范围内,但 C 中的任意两个元素都不在彼此的容差范围内。

如果 ByRows 选项为 true,则 C 为一个矩阵,其中包含 A 中的唯一行。在这种情况下,C 中的行将按第一列的升序排序。A 中的每行都处于 C 中的行的容差范围内,但 C 中的任意两行都不在彼此的容差范围内。

A 的索引,以重复元素首次出现处的索引的列向量形式或元胞数组形式返回。IA 通常满足 C = A(IA),以下情况例外:

  • 如果 ByRows 选项为 true,则 C = A(IA,:)

  • 如果 OutputAllIndices 选项为 true,则 IA 为元胞数组且 C(i)~A(IA{i}),其中 ~ 意味着各个值均处于彼此的容差范围内。

C 的索引,以索引的列向量形式返回。IC 满足下列属性,其中 ~ 意味着各个值处于彼此的容差范围内。

  • 如果 A 是向量,则 A~C(IC)

  • 如果 A 是矩阵,则 A(:)~C(IC)

  • 如果 ByRows 选项为 true,则 A~C(IC,:)

算法

uniquetol 以字典的编纂方式对输入进行排序,然后从最低值或最高值开始寻找容差范围内的唯一值。因此,更改输入的排序会更改输出。例如,uniquetol(-A) 给出的结果可能与 -uniquetol(A) 所给出的结果不同。

这些可以是满足该条件的多个有效 C 输出,C 中的任意两个元素都不在彼此的容差范围内uniquetol 函数可以返回多个有效输出,具体取决于 occurrence 的值是 'highest' 还是 'lowest' 以及是否指定 PreserveRange 选项。

扩展功能

版本历史记录

在 R2015a 中推出

全部展开