不规则网格的2D插值Fortran实现

4

如何在FORTRAN中实现二维插值,其中数据看起来如下所示。 x和y是两个坐标,z是依赖它们的值 x间隔均匀,但y间隔不均匀且随着x的均等值而增加。 在不损失太多精度的情况下-

  • 基于给定的x和y,获取z值的最简单方法是什么?
  • 基于给定的x和y,获取z值的最快方法是什么?

谢谢 SM

x    y    z
-----------
0   0     -
0   0.014 -
0   0.02  -

.....
....

0.1 0     -
0.1 0.02  -
0.1 0.03  - 

.......
.....

1.0  0     -
1.0  0.05  -
1.0  0.08  -

.......
.......
3个回答

8
我假设您已经按照您提供的格式将数据读入了一个 N x 3 的数组中。我假设您不知道 X 间距 - 您肯定不知道 Y 间距,因此我建议采用以下策略:
  • 找出 X 间距:从第一行开始,遍历 X 元素,直到看到值发生变化。现在您知道 XSTART 和 XSTEP - 您以后需要用到它们。
  • 在数组中进行二分查找,查找值为 X,直到找到一个值 XFOUND,使得 XFOUND < X < XFOUND + XSTART
  • 假设您指向“列表中的某个位置”,找到相应的 Y 值 - 根据它是比所需值大还是小,您向上或向下遍历数组,直到找到第一个条目 < Y。相应的值是 X11、Y11 和 Z11。数组中的下一行有 X12、Y12 和 Z12。
  • 在执行插值之前,您需要再找到两个点 - 重复这个过程,寻找“更大的 X 值”。这将给您 XYZ21 和 XYZ22。
  • 现在您可以考虑计算插值的 Z 值。通常有不同的技术,精度也不同:
  • “最近邻”:找到最近的点,并使用其 Z 值(最简单,最不准确)
  • “线性插值”:找到三个最近的点,并根据相对距离进行值的线性插值
  • “更高阶估计”:要做到这一点,您通常需要创建一个完整的网格点连接映射,以便进行样条插值,并获得在网格点之间通常更准确的平滑插值(假设样本描述的函数实际上是光滑函数!)
我的 FORTRAN 有点生疏 - 希望这能帮到您。
PS - 可能更简单的方法是利用 X 值已经均匀分布的事实。这使您可以进行更好的插值。请参见此图片:

谢谢你的回答。我一直在尝试实现这个。但问题是如何转换为矩形网格?我拥有的数据几乎是抛物线形状,其中x均匀间隔,但y从0到最大值变化,然后再从0开始。 - user1117812
1
你是说y数据没有排序? - Floris
是的,Y数据没有排序,我认为它不能排序,因为Y的值取决于X,例如y^2 = 4ax(虽然不完全相同)。 - user1117812
3
我所描述的方法只需要你找到四个“非矩形”角点,其中 y11 < Y, y21 < Y, y12 > Y, y22 > Y。即使对于未排序的数组,你也可以找到这些点;然后,使用我给出的方程将其转换为矩形网格并插值。建议查看 @Simon 的建议以查看 GEOMPACK 以获取 Delaunay 三角剖分 - 然后您可以使用 重心插值。进行一次在矩形网格上的值获取后,就可以使用快速插值。 - Floris
1
如果速度是一个关键问题,创建一个矩形网格然后在其中进行插值很可能比在三角形网格中进行插值更快。我认为,构建一次三角剖分并在其中进行插值以生成矩形网格是一个不错的方法。需要注意的是,在由插值构建的网格中进行插值有可能引入额外的误差。因此,对于精度至关重要的情况,我建议保留三角形网格进行插值。 - Simon
我已经用球坐标完成了这个。如果有人感兴趣,我可以分享代码!这肯定比@Simon的答案快得多,但是它依赖于问题几何形状的假设。在这种方法中确定四个角的索引可能是最大的瓶颈。如果y值被排序——也许提前排序,如果它们保持不变?——二分搜索算法将是一个最优的方法。 - jvriesem

6

在找到解决这个问题的最快方法之前,我建议先找到一种解决问题的方法。简而言之,我建议:

1) 找到(x,y)点的Delaunay三角剖分。例如,Fortran代码可在GEOMPACK中找到。

2) 在进行插值时,给定Delaunay三角剖分,找到包含插值点的三角形,然后根据点相对于每个三角形顶点的位置插值z值。

(编辑) 我忘记了这个方法的名称(如果我曾经知道的话),但是感谢@Floris,一种好的三角插值方法称为重心插值,它基于通过从大三角形内部的一个点向三角形的每个角落绘制线条将大三角形分成三个较小三角形的面积比率来找到插值值。每个小三角形的面积可以使用Heron公式根据三角形的每条边的长度来找到。

如果需要加速改进,我认为主要可以通过找到快速查找包含插值点的三角形的方法来实现,但在选择要优化的代码部分之前,我想对一些测试运行进行性能分析。


对于三维空间中的[x,y,z]点,在二维[x1,y1] [x2,y2] [x3,y3] Delaunay面片内插一个点[x,y,zi]的重心插值,如果z值是高程,则等同于在三维Delaunay面片上的精确位置,是吗?这是假设没有垂直重叠的面片。 - Adam Erickson
1
GEOMPACK的更新链接:https://people.sc.fsu.edu/~jburkardt/f77_src/geompack/geompack.html。 - jvriesem


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接