文档

基于网格插值

这个例子展示了如何创建一个griddedInterpolant以及如何有效地使用它来执行基于网格的插值。

网格是组织数据的一种常用而有用的方法。这种数据格式表示离散网格点位置的值或强度。基于网格的数据也适合MATLAB®提供的基于数组的环境。

当我们处理网格数据时,我们经常需要知道位置上的值而不是网格点上的值。通常,我们可能需要细化网格以提高分辨率,或者如果网格包含的细节比我们实际需要的更多,则需要重新细化网格。基于网格的插值提供了执行这些任务所需的功能。

MATLAB提供了INTERP函数家族来支持在网格上的插值万博1manbetxNDGRIDMESHGRID格式。的griddedInterpolant类提供类似的功能。它的设计目的是支持NDGRID格式的万博1manbetx网格插值,并尽可能利用内存和性能优势。当以重复的方式插入相同的网格时,这些改进很明显。在这个场景中,开销是累积的。的griddedInterpolant通常可以胜过INTERP1/2/3/N函数,因为它能够缓存和重用相同的插值函数。

细化粗糙网格

这个例子向你展示了如何创建一个griddedInterpolant对网格数据集进行插值,然后对更细的网格进行插值。我们将从定义一个为X和Y输入生成值的函数开始:

generatevalues = @ (X, Y) (3 * (1 - X) ^ 2。* exp (- (X ^ 2) (Y + 1) ^ 2)。...- 10*(X/5 -X ^3 - y ^5).*exp(-X.^2-Y.^2)...- * exp (1/3 (X + 1)。^ 2 - y ^ 2));

我们可以创建一个2D网格,然后将它传递给generatevalues函数生成网格点上的值。网格由一对网格向量组成,如下所示:

xgv = -1.5:0.25:1.5;ygv = 3:0.5:3;(X, Y) = ndgrid (xgv ygv);

现在生成值数据:

V = generatevalues (X, Y);

我们可以为这个数据集创建一个支持网格内插值的插值。万博1manbetx由于插值的行为像一个函数,我们将给它的变量名F. '立方'选项指定立方插值。

F = griddedInterpolant(X, Y, V,“立方”
F = griddedInterpolant with properties: GridVectors: {[1x13 double] [1x13 double]} Values: [13x13 double] Method: 'cubic' ExtrapolationMethod: 'cubic'

插值函数F有3个属性:GridVectors实际上是我们用来创建网格的矢量xgv和ygv。插值器以griddvectors的紧凑形式存储网格。如果网格很大,这可以节省内存。GridVectors是一个单元格数组,所以我们可以如下查询内容:

gridvectorprop = F.GridVectors
gridvectorprop =1 x2单元阵列{1x13 double} {1x13 double}
firstgridvector = F.GridVectors {1}
firstgridvector =1×13-1.5000 -1.2500 -1.0000 -0.7500 -0.5000 -0.2500 0 0.2500 0.5000 0.7500 1.0000 1.2500
secondgridvector = F.GridVectors {2}
secondgridvector =1×13-3.0000 -2.5000 -2.0000 -1.5000 -1.0000 -0.5000 0 0.5000 1.0000 1.5000 2.0000 2.5000 3.0000⋯⋯

网格点上的值存储在values数组中。您可以使用标准MATLAB语法访问这些值,以便在数据中建立索引。例如,检查4乘5的间隔:

first4x5values = F.Values(1:4, 1:5)
first4x5values =4×50.0042 0.0028 0.0452 0.3265 0.3007 -0.0050 -0.0671 -0.1285 0.3923 0.9838 -0.0299 -0.2346 -0.5921 0.1483 1.8559 -0.0752 -0.5260 -1.4478 -0.6798 2.4537

插值技术由Method属性表示。我们选择了三次插值,我们的选择体现如下:

theinterpolationmethod = F.Method
theinterpolationmethod =“立方”

我们现在可以创建一个更精细的网格,并使用插值来计算这些点的值。我们将这些点称为查询点(Xq, Yq),以将它们与原始样本点区分开来。

xqgv = -1.5:0.1:1.5;yqgv = 3:0.1:3;[Xq, Yq] = ndgrid (xqgv yqgv);

现在,我们可以在经过优化的网格上计算相应的值Vq (Xq, Yq)。因为我们将插值函数命名为F,所以调用语法是

Vq = F(Xq, Yq);

现在我们可以生成一个图来与最初的粗略图进行比较。

图冲浪(X, Y, V)标题(“网格数据集”“fontweight”“b”);

figure surf(Xq, Yq, Vq);标题(“使用立方插值优化网格数据集”“fontweight”“b”);

查询Interpolant

我们可以在网格域内的任何位置查询插值。

F (0.9, 2.0)
ans = 2.6536

您可以将这个插值值与解析表达式生成的值进行比较。

generatevalues (0.9, 2.0)
ans = 2.6519

您可以使用查询点数组而不是查询坐标数组来查询插值。我们可以通过查询网格中的随机位置来显示这一点。

Xq = -1.5 + 3.*rand(5,2);Vq = F (Xq)
Vq =5×1-1.7032 2.0861 2.5200 2.1331 6.3799

或者使用替代语法:

Vq = F(Xq(:,1), Xq(:,2))
Vq =5×1-1.7032 2.0861 2.5200 2.1331 6.3799

内插器支持网格域内的查询。万博1manbetx如果您的查询点位于网格的域之外,插值器将返回一个NaN。

F(4、5)
ans = 29.0622

选择不同的插值方法

您可以动态更改插值方法。例如,如果你希望使用样条方法而不是三次,你可以改变它如下:

F.Method =样条的
F = griddedInterpolant with properties: GridVectors: {[1x13 double] [1x13 double]} Values: [13x13 double] Method: 'spline' ExtrapolationMethod: 'cubic'

我们可以使用样条插值方法重新计算和绘图。

xqgv = -1.5:0.1:1.5;yqgv = 3:0.1:3;[Xq, Yq] = ndgrid (xqgv yqgv);Vq = F(Xq, Yq);

现在我们可以生成一个图来与最初的粗略图进行比较。

图冲浪(X, Y, V)标题(“网格数据集”“fontweight”“b”);

figure surf(Xq, Yq, Vq);标题(“使用样条插值优化网格数据集”“fontweight”“b”);

插值的数据MESHGRID格式

griddedInterpolant类被设计用于处理符合NDGRID格式。这为一般的n维网格提供了支持万博1manbetx,包括可视为退化网格的一维网格。相比之下,MESHGRID格式只能支持2D和3D的网格。万博1manbetx两种网格类型具有相同的网格点坐标;不同之处在于坐标数组的格式。

如果你想创建一个griddedInterpolant使用MESHGRID数据,您需要将数据转换为NDGRID格式。在2D中,这涉及到数组的转置,如下面的例子所示。

xgv = -1.5:0.25:1.5;ygv = 3:0.5:3;(X, Y) = meshgrid (xgv ygv);V = generatevalues (X, Y);

要将数据转换为NDGRID格式,请应用转置

X = X ';Y = Y ';V = V ';

我们现在可以创建插值

F = griddedInterpolant(X, Y, V)
F = griddedInterpolant with properties: GridVectors: {[1x13 double] [1x13 double]} Values: [13x13 double] Method: 'linear' ExtrapolationMethod: 'linear'

转换3 dMESHGRID数据NDGRID格式包括调换3D数组的每一页。这是通过使用交换函数来交换行(维度1)和列(维度2)。下面是一个示例,演示如何:

全球之声=三3;[X, Y, Z] = meshgrid(问);V = x ^2 + y ^2 + z ^2;P = [2 1 3];X =排列(X, P);Y =排列(Y, P);Z =排列(Z, P);V =排列(V, P);

我们现在可以创建插值

F = griddedInterpolant(X, Y, Z, V)
F = griddedInterpolant with properties: GridVectors: {1x3 cell} Values: [7x7x7 double] Method: 'linear' ExtrapolationMethod: 'linear'

同样地,当使用MESHGRID,改进的性能可以通过转换来实现NDGRID格式。例如,如果我们想用a来查询插值函数FMESHGRID由查询点(Xq, Yq, Zq)组成,我们可以将数据转换为NDGRID格式如下:

[Xq, Yq, Zq] = meshgrid(0:0.5:2);Xq =排列(Xq, P);Yq =排列(Yq P);Zq =排列(Zq、P);

(Xq, Yq, Zq)现在在NDGRID格式,可以有效查询。

Vq = F (Xq, Yq Zq);

插值一般尺寸的网格

griddedInterpolant类别不限于2维和3维。你可以创建一个插值为1D, 4D或更高。在实践中,表示数据所需的内存可能是高维的限制因素。根据网格点的数量和可用计算能力,此限制可能影响相对较低的维数(小于10维)的使用。下面的例子说明了使用PCHIP插值方法的一维插值。

X = 1:6;V = [16 18 21 17 15 12];F = griddedInterpolant (X, V,“pchip”
F = griddedInterpolant with properties: GridVectors: {[1 2 3 4 5 6]} Values: [16 18 21 17 15 12] Method: 'pchip' ExtrapolationMethod: 'pchip'

我们现在可以在一个更细的区间内计算插值。

Xq = 1:0.05:6;Vq = F (Xq);

用蓝色绘制查询点,用红色绘制插值结果,我们得到:

情节(X, V,“ob”Xq矢量量化,“- r”)标题(使用PCHIP方法的数据集的1D插值“fontweight”“b”);

我们可以创建和查询一个4D插值如下:

[X1, X2, X3, X4] = ndgrid(1:6);V = X1。^ 2 + X2。^ 2 + X3。^ 2 + X4。^ 2;F = griddedInterpolant (X1, X2, X3, X4, V)
F = griddedInterpolant with properties: GridVectors: {1x4 cell} Values: [6x6x6x6 double] Method: 'linear' ExtrapolationMethod: 'linear'

在单个4D点上进行评估

F (1.1, 2.1, 3.1, 4.1)
ans = 32.4000

比较

(1.1)平方+(2.1)平方+(3.1)平方+(4.1)平方
ans = 32.0400

在一个四维点数组中求值

Xq = 1 + 5*rand(5,4);Vq = F (Xq)
Vq =5×148.0991 68.1209 101.5174 87.5036 81.8984

插值在每个网格点上有多个值的网格

在某些应用程序中,可能有多个值与每个网格点相关联,我们可能希望依次插入每个值集。例如,如果我们有一个代表图像像素的网格,那么每个网格点可能有三种颜色强度(RGB)。有两种方法可以插入这些数据。一种方法是为这三个数据集分别创建一个插值。另一种方法是创建一个插值并替换值。下面的示例演示了使用单个插值器替换值的方法。

xgv = -1.5:0.25:1.5;ygv = 3:0.5:3;(X, Y) = ndgrid (xgv ygv);为这个网格创建两个不同的值集x ^3 - 3*(y ^2)V2 = 0.5*(x .²)- 0.5*(y .²);%现在为第一个值集创建一个插值F = griddedInterpolant (X, Y, V1,“立方”
F = griddedInterpolant with properties: GridVectors: {[1x13 double] [1x13 double]} Values: [13x13 double] Method: 'cubic' ExtrapolationMethod: 'cubic'

我们可以在一个精炼的网格上评估V1数据集并绘制结果

xqgv = -1.5:0.1:1.5;yqgv = 3:0.1:3;[Xq, Yq] = ndgrid (xqgv yqgv);Vq1 = F (Xq, Yq);图冲浪(Xq, Yq Vq1);标题(“V1数据集的立方插值”“fontweight”“b”);

我们可以重用插值器,通过替换Values数据来插值第二个数据集。

F.Values V2 =
F = griddedInterpolant with properties: GridVectors: {[1x13 double] [1x13 double]} Values: [13x13 double] Method: 'cubic' ExtrapolationMethod: 'cubic'
Vq2 = F (Xq, Yq);图冲浪(Xq, Yq Vq2);标题(“V2数据集的立方插值”“fontweight”“b”);

插值大型数据集

griddedInterpolant类相对有效地处理大型数据集。这些数据集可能由外部生成并导入MATLAB的值网格组成。例如,由外部源扫描的大型2D或3D图像。此外,此类数据集可能没有明确定义的坐标数组网格。如果数据集是一个大的3D图像,网格坐标数组的引入将使内存增加四倍。

griddedInterpolant类允许您从值网格和默认的网格然后从数组的大小推导出。这个默认网格定义为网格向量-一个紧凑的网格表示,使用很少的内存。

为了说明这一点,我们可以使用PEAKS函数生成一个值数组,然后为这个数据集创建一个插值,如下所示:

V =山峰(10);F = griddedInterpolant (V,“立方”
F = griddedInterpolant with properties: GridVectors: {[1 2 3 4 5 6 7 8 9 10] [1 2 3 4 5 6 7 8 9 10]} Values: [10x10 double] Method: 'cubic' ExtrapolationMethod: 'cubic'

GridVectors性质,我们可以观察到的向量是由V数组的大小推导出来的。V是一个10x10的数组,对应的网格向量为1:10和1:10

firstgridvector = F.GridVectors {1}
firstgridvector =1×101 2 3 4 5 6 7 8 9 10
secondgridvector = F.GridVectors {2}
secondgridvector =1×101 2 3 4 5 6 7 8 9 10

我们可以插入一个精致的网格来提高分辨率,幸运的是,我们不需要创建一个完整的网格来做这件事。我们可以使用一对网格向量来计算,并将它们封装在花括号{}中来传达这个意图。默认网格的比例是1:10,所以我们将使用1:0.5:10来优化半间隔。对应的查询值Vq如下:

Vq = F({1:0.5:10, 1:0.5:10});

我们现在可以把结果并排画出来。

图冲浪(V);标题(的样本值“fontweight”“b”);

图冲浪(Vq);标题(“使用紧凑网格的立方插值”“fontweight”“b”);

注意:当我们绘制曲面时,SURF函数也使用默认网格来生成绘图。在第一个图中,值由一个10 × 10的数组表示,第二个图是一个20 × 20的数组。因此轴上有0到10和0到20的刻度。

当你创建插值时,可以通过指定网格向量来覆盖默认网格。例如,我们可以这样构造插值函数:

F = griddedInterpolant({10:19, 20:29}, V,“立方”
F = griddedInterpolant with properties: GridVectors: {[10 11 12 13 14 15 16 17 18 19] [1x10 double]} Values: [10x10 double] Method: 'cubic' ExtrapolationMethod: 'cubic'

评估将按照同样的比例进行

F(15、25)
ans = -0.0531

默认的网格向量也可以被替换为:

F.GridVectors = {10:19, 20:29}
F = griddedInterpolant with properties: GridVectors: {[10 11 12 13 14 15 16 17 18 19] [1x10 double]} Values: [10x10 double] Method: 'cubic' ExtrapolationMethod: 'cubic'

以重复方式插入数据集

在某些应用程序中,可能需要以重复的方式插入相同的数据集。的griddedInterpolant类通常可以比INTERP函数更有效地处理这种场景。的griddedInterpolant类能够重用在前一个查询期间计算的数据,以加快后续查询的计算。下面的例子展示了这种优势:

样本数据集

[X, Y, Z] = ndgrid(1:100);V = x ^2 + y ^2 + z ^2;

性能数据INTERPN

抽搐;i = 1:1000 Xq = 100*rand();Yq = 100 * rand ();Zq = 100 * rand ();Vq = interpn (X, Y, Z, V, Xq Yq, Zq、“立方”);结束interpnTiming = toc
interpnTiming = 12.8663

性能数据griddedInterpolant

抽搐;F = griddedInterpolant (X, Y, Z, V,“立方”);i = 1:1000 Xq = 100*rand();Yq = 100 * rand ();Zq = 100 * rand ();Vq = F (Xq, Yq Zq);结束griddedInterpolantTiming = toc
griddedInterpolantTiming = 0.1528
这个话题有用吗?