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)

Figure contains an axes object. The axes object contains 2 objects of type line. One or more of the lines displays its values using only markers

创建一个随机数向量,并使用容差确定唯一元素。将 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

Figure contains an axes object. The axes object contains 20 objects of type line. One or more of the lines displays its values using only markers

输入参数

全部折叠

查询数组,指定为标量、向量、矩阵或多维数组。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 中推出

全部展开