zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Matlab中uniquetol函数使用

MATLAB 函数 使用
2023-09-11 14:14:48 时间

目录

语法

说明

示例

存在数值错误的情况下的唯一元素

确定唯一行

准备要进行精确比较的向量

使用大容差对数据分割子集

向量中的平均类似值

指定绝对容差

按列指定 DataScale


        容差内的唯一值

语法

C = uniquetol(A,tol)

C = uniquetol(A)

[C,IA,IC] = uniquetol(___)

[___] = uniquetol(___,Name,Value)

说明

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

abs(u-v) <= tol*max(abs(A(:))),即,uniquetol 基于数据量级调整 tol 输入。

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

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

[C,IA,IC] = uniquetol(___) 返回索引向量 IA 和 IC,满足 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);

        通过取差值来验证 x 和 y 不同。

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 找出 A 和 B 中的唯一行。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);

        将 x 和 y 合并为单个向量 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 与 == 或验证全等的函数结合使用,如 isequal 或 unique

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

使用大容差对数据分割子集

        创建一个由二维样本点组成的云,这些样本点限定在一个以点 (1/2,1/2)  为圆心,以 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

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);

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的两个较小值。指定tol 和 DS以生成满足容差范围的等式: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

按列指定 DataScale

        创建一个随机二维点集,然后使用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);

        绘制每个条带的点和平均值。

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