主要内容

分散数据插值

分散的数据

分散数据由一组点组成X和相应的值V,这些点的相对位置之间没有结构或顺序。对分散数据进行插值有多种方法。一种广泛使用的方法是对点进行Delaunay三角剖分。

这个例子展示了如何通过对点进行三角化并将顶点提升一个幅度来构造插值曲面V正交的维度X

对于如何应用此方法,有不同的方法。在这个例子中,插值被分解成单独的步骤;通常,整个插值过程是通过一个函数调用来完成的。

在抛物面表面上创建一个分散的数据集。

X = [-1.5 3.2;1.8 - 3.3;-3.7 - 1.5;-1.5 - 1.3;...0.8 - 1.2;3.3 - 1.5;-4.0 - -1.0;-2.3 - -0.7;0 -0.5;2.0 - -1.5;3.7 - -0.8;-3.5 - -2.9;...-0.9 - -3.9;2.0 - -3.5;3.5 - -2.25);V = x(:,1)。^2 + x (:,2).^2;持有plot3 (X (: 1) X(:, 2), 0(15日1),“* r”)轴([- 4,4,- 4,4,0,25]);网格stem3 (X (: 1), (:, 2), V,“^”“填满”)举行视图(322.5,30);

图中包含一个轴对象。axis对象包含line、stem类型的2个对象。

创建一个Delaunay三角剖分,提升顶点,并在查询点计算插值Xq

图(“颜色”“白色”) t = delaunay(X(:,1),X(:,2));持有trimesh (t) X (: 1), X(:, 2), 0(15日1),...“EdgeColor”“r”“FaceColor”“没有”) defaultFaceColor = [0.6875 0.8750 0.8984];trisurf (t) X (: 1), X (:, 2), V,“FaceColor”...defaultFaceColor,“FaceAlpha”, 0.9);plot3 (X (: 1) X(:, 2), 0(15日1),“* r”)轴([- 4,4,- 4,4,0,25]);网格plot3 (-2.6, -2.6, 0,‘* b”“线宽”, 1.6) plot3([-2.6 - -2.6],[-2.6 - -2.6],[0 13.52]”,“- b”“线宽”, 1.6)视图(322.5,30);文本(-2.0,-2.6,Xq的“FontWeight”“大胆”...“HorizontalAlignment”“中心”“写成BackgroundColor”“没有”);

图中包含一个轴对象。axis对象包含patch、line、text类型的6个对象。

此步骤通常涉及遍历三角剖分数据结构,以查找包含查询点的三角形。找到点后,计算值的后续步骤取决于插值方法。您可以计算邻域中最近的点,并使用该点的值(最近邻插值方法)。你也可以计算三角形的三个顶点的值的加权和(线性插值方法)。这些方法和它们的变体包括在文本和参考分散数据插值。

虽然插图强调了2-D插值,但您可以将此技术应用于更高维度。更一般地说,给定一组点X和相应的值V,则可以构造该形式的插值函数V = f (x).您可以在查询点计算插值Xq,给予Vq = F(Xq).这是一个单值函数;对于任何查询点Xq的凸包内X,它将产生独特的价值矢量量化.假设样本数据尊重这一性质,以产生一个令人满意的插值。

MATLAB®提供两种方法来执行基于三角测量的分散数据插值:

griddata函数支持二维分散数金宝app据插补。的griddatan函数支持N-D离散金宝app数据插值;然而,对于中等到大型的点集,它在高于6-D的维度上是不实用的,因为底层三角剖分所需要的内存呈指数增长。

scatteredInterpolant类支持二维和金宝app三维空间的离散数据插值。我们鼓励使用这个类,因为它更有效,并且易于适应更广泛的插值问题。

用griddata和griddatan插值散点数据

griddata而且griddatan函数取一组样本点,X,对应的值,V,和查询点,Xq,并返回插值的值,矢量量化.每个函数的调用语法都类似;主要的区别是2-D和3-Dgriddata函数让你定义点XY/XYZ坐标。这两个函数在预定义的网格点位置插入分散的数据;其目的是生成网格化数据,因此得名。插值在实践中更为普遍。你可能想要在点的凸包内的任意位置进行查询。

这个例子展示了如何griddata函数在一组网格点上插入分散的数据,并使用该网格化数据创建等高线图。

画出海底山数据集(a)海底山是一座水下的山)。该数据集由一组经度(x)和纬度(y)位置,以及相应的海底山海拔高度(z)在这些坐标上测量。

负载海底山plot3 (x, y, z,“。”“markersize”(12)包含“经”) ylabel (“纬度”) zlabel (“脚的深度”网格)

图中包含一个轴对象。axis对象包含一个line类型的对象。

使用meshgrid在经纬度平面上创建一组二维网格点,然后使用griddata在这些点上插入相应的深度。

图(xi, yi) = meshgrid (210.8:0.01:211.8 -48.5:0.01: -47.9);Zi = griddata(x,y,z,xi,yi);冲浪(xi,咦,zi);包含(“经”) ylabel (“纬度”) zlabel (“脚的深度”

图中包含一个轴对象。axis对象包含一个surface类型的对象。

现在数据是网格格式的,计算并绘制等高线。

图[c,h] =等值线(xi,yi,zi);clabel (c、h);包含(“经”) ylabel (“纬度”

图中包含一个轴对象。坐标轴对象包含一个轮廓类型的对象。

你也可以使用griddata在数据集的凸包内的任意位置进行插值。例如,坐标(211.3,-48.2)处的深度为:

Zi = griddata(x,y,z, 211.3, -48.2);

基本的三角剖分是在每次griddata函数被调用。如果使用不同的查询点重复插入相同的数据集,则会影响性能。的scatteredInterpolant类中描述的使用scatteredInterpolant类插值分散数据在这方面更有效率。

MATLAB软件还提供griddatan支持更金宝app高维度的插值。调用语法类似于griddata

scatteredInterpolant类

griddata函数在需要插值以查找一组预定义格点位置上的值时非常有用。在实践中,插值问题往往比较一般,而scatteredInterpolant类提供了更大的灵活性。该类具有以下优点:

  • 它生成了一个可以有效查询的插值函数。也就是说,底层三角测量只创建一次,并在后续查询中重用。

  • 插值方法可以独立于三角剖分而改变。

  • 数据点上的值可以独立于三角剖分而改变。

  • 数据点可以增量地添加到现有的插值器中,而无需触发完整的重新计算。数据点也可以有效地删除和移动,前提是编辑的点数量相对于样本点的总数较小。

  • 它提供了外推功能,用于逼近落在凸包之外的点的值。看到外推分散的数据获取更多信息。

scatteredInterpolant提供以下插值方法:

  • “最近的”-最近邻插值,插值曲面不连续。

  • “线性”-线性插值(默认),其中插值曲面是连续的C0。

  • “天然”-自然邻居插值,其中插值面是C1连续的,除了在样本点。

scatteredInterpolant类支持二维和金宝app三维空间的离散数据插值。你可以通过调用来创建插值scatteredInterpolant以及传递点的位置和相应的值,以及可选的插值和外推方法。看到scatteredInterpolant类的语法的详细信息,请参阅scatteredInterpolant

使用scatteredInterpolant类插值分散数据

这个例子展示了如何使用scatteredInterpolant来插值一个分散的抽样山峰函数。

创建分散的数据集。

rng默认的;X = -3 + 6。*兰德(250 [2]);V =峰值(X(:,1),X(:,2));

创建插值。

F = scatter interpolant (X,V)
F = scatteredInterpolant with properties: Points: [250x2 double]值:[250x1 double]方法:'linear' ExtrapolationMethod: 'linear'

属性表示数据点的坐标,而属性表示关联的值。的方法属性表示执行插值的插值方法。的ExtrapolationMethod属性表示查询点落在凸包之外时使用的外推方法。

的属性F的字段,以同样的方式访问结构体.例如,使用F.Points检查数据点的坐标。

求插值值。

scatteredInterpolant提供插值器的下标求值。它的计算方法与函数相同。你可以计算插值如下。在本例中,查询位置的值由矢量量化.你可以在一个查询点上计算:

Vq = F([1.5 1.25])
Vq = 1.4838

你也可以传递单独的坐标:

Vq = F(1.5, 1.25)
Vq = 1.4838

你可以在点位置的向量上求值:

Xq = [0.5 0.25;0.75 - 0.35;1.25 - 0.85);Vq = F(Xq)
Vq =3×10.4057 1.2199 2.1639

你可以评估F在网格点位置并绘制结果。

[Xq,Yq] = meshgrid(-2.5:0.125:2.5);Vq = F(Xq,Yq);冲浪(Xq Yq Vq);包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”);zlabel (“值- V”“fontweight”“b”);标题(“线性插值法”“fontweight”“b”);

图中包含一个轴对象。标题为“线性插值方法”的axis对象包含一个类型为surface的对象。

修改插补方法。

你可以在飞行中改变插值方法。将方法设置为“最近的”

F.Method =“最近的”

像以前一样重新计算并绘制插值函数。

Vq = F(Xq,Yq);图冲浪(Xq, Yq Vq);包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”) zlabel (“值- V”“fontweight”“b”)标题(“最近邻插值法”“fontweight”“b”);

图中包含一个轴对象。标题为“最近邻插值方法”的axis对象包含一个类型为surface的对象。

将插值方法改为自然邻域,重新计算,并绘制结果。

F.Method =“天然”;Vq = F(Xq,Yq);图冲浪(Xq, Yq Vq);包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”) zlabel (“值- V”“fontweight”“b”)标题(“自然邻居插值法”“fontweight”“b”);

图中包含一个轴对象。标题为“自然邻居插值方法”的坐标轴对象包含一个类型为surface的对象。

替换样本数据位置的值。

您可以更改这些值V在样本数据位置,X,在飞行中。这在实践中很有用,因为一些插值问题可能在同一位置有多个值集。例如,假设您想插值一个由位置(xyz)和相应的组件化速度向量(VxvVz).您可以通过将每个速度分量分配给values属性(V)依次。这具有重要的性能优势,因为它允许您重用相同的内插,而不会每次都产生计算新内插的开销。

下面的步骤展示了如何更改示例中的值。您将使用表达式计算值, v x e - x 2 - y 2

V = X(:,1).*exp(-X(:,1).^2-X(:,2).^2);F.Values = V;

求插值值并绘制结果。

Vq = F(Xq,Yq);图冲浪(Xq, Yq Vq);包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”) zlabel (“值- V”“fontweight”“b”)标题(' v = x.*exp(-x.^2-y.^2)的自然邻居插值'

图中包含一个轴对象。标题为N a t r a l空白N e g h b o r空白i N e r p o la t o N空白o f空白v blank =空白x。* e x p (- x。平方基线- y。Squared baseline)包含一个类型为surface的对象。

向现有的插值器添加额外的点位置和值。

这将执行有效的更新,而不是使用增强的数据集进行完整的重新计算。

在添加示例数据时,重要的是要同时添加点位置和相应的值。

继续这个例子,创建新的样本点如下所示:

X = -1.5 + 3.*兰特(100,2);V = X(:,1).*exp(-X(:,1).^2-X(:,2).^2);

将新的点和相应的值添加到三角剖分中。

F.Points(end+(1:100),:) = X;F.Values(end+(1:100)) = V;

求出改进后的插值值并绘制结果。

Vq = F(Xq,Yq);图冲浪(Xq, Yq Vq);包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”);zlabel (“值- V”“fontweight”“b”);

图中包含一个轴对象。axis对象包含一个surface类型的对象。

从插值器中删除数据。

您可以增量地从插值器中删除样本数据点。您还可以从插值器中删除数据点和相应的值。这对于去除虚假异常值很有用。

在删除样本数据时,重要的是同时删除点位置和相应的值。

去掉第25点。

F.Points(25,:) = [];F.Values(25) = [];

去掉第5到15点。

F.Points(5:15,:) = [];F.Values(5:15) = [];

保留150点,去掉其余的。

F.Points(150:end,:) = [];F.Values(150:end) = [];

当你评估和绘图时,这会创建一个更粗糙的表面:

Vq = F(Xq,Yq);图冲浪(Xq, Yq Vq);包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”);zlabel (“值- V”“fontweight”“b”);标题(' v = x.*exp(-x.^2-y.^2)剔除样本点后的插值'

图中包含一个轴对象。标题为I n t r p o la I o n blank o f blank v blank = blank x的轴对象。* e x p (- x。平方基线- y。平方基线)空白w i t h空白s m p l e空白p ont s空白re m o v d包含一个类型为surface的对象。

复杂分散数据插值

这个例子展示了当每个样本位置的值很复杂时,如何插值分散的数据。

创建示例数据。

rng (“默认”X = -3 + 6*rand([250 2]);V = complex(X(:,1).*X(:,2), X(:,1)。^2 + x (:,2).^2;

创建插值。

F = scatter interpolant (X,V);

创建一个由查询点组成的网格,并在网格点处计算插值。

[Xq,Yq] = meshgrid(-2.5:0.125:2.5);Vq = F(Xq,Yq);

的实分量矢量量化

VqReal = real(Vq);图冲浪(Xq, Yq VqReal);包含(“X”);ylabel (“Y”);zlabel (“真实价值- V”);标题(“内插值的实分量”);

图中包含一个轴对象。标题为插值值实分量的axis对象包含一个类型为surface的对象。

的虚分量矢量量化

VqImag = imag(Vq);图冲浪(Xq, Yq VqImag);包含(“X”);ylabel (“Y”);zlabel (虚值- V);标题(“内插值的虚分量”);

图中包含一个轴对象。名为“插值值的虚分量”的axis对象包含一个类型为surface的对象。

分散数据插值问题的解决

前几节中的许多说明性示例处理了在光滑表面上采样的点集的插值。此外,这些点的间距相对均匀。例如,点簇之间并没有相对较大的距离。此外,插值在点位置的凸包内得到了很好的评价。

在处理真实世界的插值问题时,数据可能更具挑战性。它可能来自测量设备,可能产生不准确的读数或异常值。底层数据可能不会平滑地变化,值可能会从一个点跳到另一个点。本节将为您提供一些识别和解决分散数据插值问题的指导方针。

包含nan的输入数据

您应该预处理包含的示例数据值,以删除作为该数据的值不能用于插值。如果一个删除时,相应的数据值/坐标也应删除,以确保一致性。如果值出现在样例数据中,构造函数将在调用时出错。

下面的示例说明如何删除年代。

创建一些数据并将一些条目替换为

X =兰特(25,1)*4-2;Y = rand(25,1)*4-2;V = x.²+ y.²;x(5) = NaN;x(10) = NaN;y(12) = NaN;V(14) = NaN;
这段代码错误:
F = scatter interpolant (x,y,V);
而是求样本点的指数S,然后构造插值函数:
nan_flags = isnan(x) | isnan(y) | isnan(V);X (nan_flags) = [];Y (nan_flags) = [];V(nan_flags) = [];F = scatter interpolant (x,y,V);
如果点位置是矩阵形式,则下面的示例类似。首先,创建数据并将一些条目替换为值。
X =兰特(25,2)*4-2;V = x(:,1)。^2 + x (:,2).^2;X(5,1) = NaN;X(10,1) = NaN;X(12,2) = NaN;V(14) = NaN;
这段代码错误:
F = scatter interpolant (X,V);
求出NaN的样本点指数,然后构造插值:
nan_flags = isnan (X (: 1)) | isnan (X (:, 2)) | isnan (V);X(nan_flags,:) = [];V(nan_flags) = [];F = scatter interpolant (X,V);

Interpolant输出NaN值

griddata而且griddatan返回方法查询凸包外的点时的值“线性”“天然”方法。方法查询相同的点,则可以得到数值结果“最近的”方法。这是因为与查询点最近的邻居同时存在于凸包内部和外部。

如果你想计算凸包外的近似值,你应该使用scatteredInterpolant.看到外推分散的数据获取更多信息。

处理重复点位置

输入数据很少是“完美的”,您的应用程序可能不得不处理重复的数据点位置。数据集中相同位置的两个或多个数据点可以具有不同的对应值。在这种情况下,scatteredInterpolant合并这些点并计算相应值的平均值。这个例子展示了scatteredInterpolant在具有重复点的数据集上执行插值。

  1. 在平面上创建一些样本数据:

    X =兰特(100,1)*6-3;Y = rand(100,1)*6-3;V = x + y;

  2. 通过将点50的坐标分配给点100来引入一个重复的点位置:

    X (50) = X (100);Y (50) = Y (100);

  3. 创建插值。请注意,F包含99个独特的数据点:

    F = scatter interpolant (x,y,V)

  4. 检查与第50个点相关的值:

    F.Values (50)

这个值是原始第50和第100个值的平均值,因为这两个数据点的位置相同:

(V (50) + V (100)) / 2
在这种情况下,插值器以合理的方式解决歧义。然而,在某些情况下,数据点可能是接近的,而不是重合的,这些位置的值可能是不同的。

在一些插值问题中,多组样本值可能对应于相同的位置。例如,一组值可能在不同时间的相同位置被记录。为了提高效率,您可以插入一组读数,然后替换这些值来插入下一组读数。

在替换存在重复点位置的值时,始终使用一致的数据管理。假设您有两组与100个数据点位置相关的值,并且希望通过替换值来依次插入每组值。

  1. 考虑两组值:

    V1 = x + 4*y;V2 = 3*x + 5*y

  2. 创建插值。scatteredInterpolant合并重复的位置,插值器包含99个唯一的样本点:

    F = scatter interpolant (x,y,V1)
    直接通过替换值F.Values = V2意味着给99个样本分配100个值。前一个合并操作的上下文丢失;样本位置的数量与样本值的数量不匹配。插值器需要解决不一致以支持查询。金宝app

在这个更复杂的场景中,有必要在创建和编辑插值器之前删除重复项。使用独特的函数求唯一点的下标。独特的还可以输出用于标识重复点的索引的参数。

[~, I, ~] = unique([x y],'first','rows');I = sort(I);x = x(I);y = y(I);V1 = V1(i);V2 = V2(i);F = scatter interpolant (x,y,V1)
现在你可以使用F对第一个数据集进行插值。然后您可以替换这些值来插入第二个数据集。
F.Values = V2;

在编辑一个分散的interpolant时实现效率

scatteredInterpolant允许您编辑表示样例值的属性(F.Values)和插值方法(F.Method).由于这些属性独立于底层三角测量,因此可以有效地执行编辑。但是,与处理大型数组一样,在编辑数据时应该注意不要意外地创建不必要的副本。当多个变量引用一个数组并编辑该数组时,就会进行复制。

在下列情况下不制作副本:

A1 =魔法(4)A1(4,4) = 11
但是,由于数组被另一个变量引用,因此在此场景中会生成一个副本。数组A1而且A2一旦编辑完成,不能再共享相同的数据:
A1 =魔术(4)A2 = A1 A1(4,4) = 32
类似地,如果将数组传递给函数并在该函数中编辑数组,则可以根据数据的管理方式进行深度复制。scatteredInterpolant包含数据,它的行为就像一个数组,在MATLAB语言中,它被称为值对象。MATLAB语言的设计目的是在将应用程序结构化为驻留在文件中的函数时提供最佳性能。在命令行上进行原型设计可能无法产生相同级别的性能。

下面的例子演示了这种行为,但应该注意的是,本例中的性能提高不能推广到MATLAB中的其他函数。

这段代码不会产生最佳性能:

X =兰特(1000000,1)*4-2;Y = rand(1000000,1)*4-2;Z = x.*exp(-x.²-y.²);抽搐;F = scatter interpolant (x,y,z);toc抽搐;F.Values = 2*z;toc
您可以将代码放在函数文件中以更有效地执行它。

当MATLAB执行一个由驻留在文件中的函数组成的程序时,它拥有代码执行的完整图像;这使得MATLAB可以优化性能。当您在命令行中输入代码时,MATLAB无法预测您接下来要输入什么,因此它无法执行相同级别的优化。通过创建可重用函数来开发应用程序是一般和推荐的实践,MATLAB将优化这种设置下的性能。

凸包附近插值结果较差

Delaunay三角剖分非常适合于离散数据插值问题,因为它具有良好的几何性质,可以产生良好的结果。这些属性是:

  • 摈弃银形三角形/四面体,而倾向于更多的等边三角形。

  • 空的圆周属性,它隐式地定义了点之间的最近邻关系。

空的圆周属性确保插值值受到查询位置附近的样本点的影响。尽管有这些特性,在某些情况下,数据点的分布可能会导致较差的结果,这通常发生在样本数据集的凸包附近。当插值产生意想不到的结果时,样本数据的图形和底层三角测量通常可以提供对问题的洞察。

这个例子显示了在边界附近恶化的插值曲面。

创建一个示例数据集,它将显示边界附近的问题。

T = 0.4*pi:0.02:0.6*pi;X1 = cos(t)';Y1 = sint '-1.02;X2 = x1;y = y *(-1);X3 = linspace(-0.3,0.3,16)';Y3 = 0 (16,1);X = [x1;x2;x3];Y = [y1;y2;y3];

现在把这些样本点举到表面上 z x 2 + y 2 插值曲面。

Z = x.²+ y.²;F = scatter interpolant (x,y,z);[xi, yi] = meshgrid (-0.3: .02:0.3, -0.0688:0.01:0.0688);zi = F(xi,yi);网格(xi,咦,zi)包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”) zlabel (“值- V”“fontweight”“b”)标题(插值结果的);

图中包含一个轴对象。标题为Interpolated Surface的axis对象包含一个类型为Surface的对象。

实际曲面为:

Zi = xi。^2 + yi.^2;图网格(xi,yi,zi)实际表面的

图中包含一个轴对象。标题为Actual Surface的axis对象包含一个类型为Surface的对象。

为了理解插值表面在边界附近恶化的原因,查看潜在的三角剖分是有帮助的:

dt = delaunayTriangulation(x,y);图绘制(x, y,“* r”)轴平等的持有triplot (dt)情节(x1, y1,“- r”)情节(x2, y2,“- r”)标题(三角剖分用于创建插值)举行

图中包含一个轴对象。名为Triangulation Used to Create The Interpolant的axes对象包含4个类型为line的对象。

红色边界内的三角形形状相对较好;它们是由接近的点构造的,插值在这个区域工作得很好。在红色边界之外,三角形是银色的,并连接彼此远离的点。没有足够的采样来准确地捕捉表面,所以这些区域的结果很差也就不足为奇了。在3d中,对三角测量的视觉检查会变得有点棘手,但查看点分布通常有助于说明潜在的问题。

MATLAB®4griddata方法,v4的,不基于三角剖分,不受边界附近插值曲面退化的影响。

[xi, yi] = meshgrid (-0.3: .02:0.3, -0.0688:0.01:0.0688);Zi = griddata(x,y,z,xi,yi,v4的);网格(xi,咦,zi)包含(“X”“fontweight”“b”), ylabel (“Y”“fontweight”“b”) zlabel (“值- V”“fontweight”“b”)标题(用v4方法从griddata中插值曲面“fontweight”“b”);

图中包含一个轴对象。标题为Interpolated surface from griddata with v4方法的axes对象包含一个类型为surface的对象。

插值的曲面griddata使用v4的方法对应于预期的实际曲面。