简体   繁体   English

二维插值不规则网格fortran

[英]2D Interpolation irregular grid fortran

How can I implement 2-dimensional interpolation in FORTRAN where the data looks like as shown below.如何在 FORTRAN 中实现二维插值,其中数据如下所示。 x and y are two co ordinates and z is a value dependent on them x is spaced evenly but y is not uniformly spaced and the maximum value of y corresponding to uniform values of x keep on increasing. x 和 y 是两个坐标,z 是依赖于它们的值 x 是均匀间隔的,但 y 不是均匀间隔的,并且与 x 的均匀值对应的 y 的最大值不断增加。 Without losing much of accuracy-在不损失太多准确性的情况下-

  • What is the simplest method to obtain a value of z based on a given x and y?根据给定的 x 和 y 获得 z 值的最简单方法是什么?
  • What is the fastest method to obtain a value of z based on a given x and y?根据给定的 x 和 y 获得 z 值的最快方法是什么?

Thanks SM谢谢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  -

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

I am going to assume you have already read your data into an array N x 3, following the format you gave. 我将假设您已经按照您提供的格式将数据读入数组N x 3。 I am assuming you don't know ahead of time what the X spacing is - you definitely don't know the Y spacing as it varies. 我假设你提前不知道X间距是什么 - 你肯定不知道Y间距因为它的变化。 Thus I would recommend the following strategy: 因此,我建议采取以下策略:

  • Figure out the X spacing: start at the first row, and go through the X elements until you see a change in value. 找出X间距:从第一行开始,然后浏览X元素,直到看到值发生变化。 You now know XSTART and XSTEP - you will need those later. 您现在知道XSTART和XSTEP - 稍后您将需要它们。
  • Do a binary search in your array for value X, until you find a value XFOUND such that XFOUND < X < XFOUND + XSTART 在数组中对值X执行二进制搜索,直到找到值XFOUND,使得XFOUND <X <XFOUND + XSTART
  • Assuming you are pointing "somewhere in the list", you find the corresponding Y value - depending on whether it's bigger or smaller than the value you need, you step up or down the array until you find the first entry < Y. The corresponding values are X11, Y11, Z11. 假设您指向“列表中的某个位置”,您会找到相应的Y值 - 取决于它是大于还是小于您需要的值,您可以向上或向下升高数组,直到找到第一个条目<Y。相应的值是X11,Y11,Z11。 The next line in the array has X12 Y12 and Z12. 阵列中的下一行有X12 Y12和Z12。
  • You need two more points before you can do the interpolation - repeat this process, looking for the "next larger value of X". 在进行插值之前,还需要两个点 - 重复此过程,寻找“下一个更大的X值”。 This will give you XYZ21 and XYZ22 这将为您提供XYZ21和XYZ22
  • Now you can think about calculating the interpolated Z value. 现在您可以考虑计算插值的Z值。 In general there are different techniques, with different accuracies: 一般来说,有不同的技术,具有不同的精度:
  • "Nearest neighbor": find the closest point, and use its value of Z (simplest, least accurate) “最近邻居”:找到最近的点,并使用其Z值(最简单,最不准确)
  • "linear interpolation": find the three closest points, and do a linear interpolation of values based on the relative distances “线性插值”:找到三个最接近的点,并根据相对距离进行值的线性插值
  • "higher order estimates": to do this, you typically need to create a full connectivity mapping of the grid points, so you can do spline interpolation and get a smooth interpolation that will typically be more accurate at points between the grid points (assuming that the function being described by the samples is in fact a smooth function!) “更高阶估计”:为此,您通常需要创建网格点的完整连接映射,这样您就可以进行样条插值并获得平滑插值,通常在网格点之间的点处更准确(假设样本描述的功能实际上是一个平滑的功能!)

My FORTRAN is a bit rusty - hope this is some help. 我的FORTRAN有点生疏 - 希望这是一些帮助。

PS - potentially a simpler approach is to use the fact that the X values are already evenly spaced. PS - 可能更简单的方法是使用X值已经均匀间隔的事实。 This allows you to make a better interpolation. 这允许您进行更好的插值。 See this picture: 看这张图:

在此输入图像描述

Before finding the fastest way to solve this problem, I'd suggest finding a way to solve the problem. 找到解决这个问题的最快方法之前,我建议寻找一种方法来解决这个问题。 In brief, I'd suggest: 简而言之,我建议:

1) Find a Delaunay triangulation of the (x,y) points. 1)找到(x,y)点的Delaunay三角剖分。 Fortran code to do this is in GEOMPACK , for instance. 例如,执行此操作的Fortran代码位于GEOMPACK中

2) To interpolate, given the Delaunay triangulation, find the triangle that contains the point where the interpolation is to be done, then interpolate the z value, based on the location of the point relative to each of the triangle vertices. 2)在给定Delaunay三角剖分的情况下进行插值,找到包含要进行插值的点的三角形,然后基于该点相对于每个三角形顶点的位置插入z值。

(EDIT) I had forgotten the name of the method (if I ever knew it) but, thanks to @Floris, a good approach to interpolate in a triangle is called barycentric interpolation , which finds the interpolated value based on the ratios of the areas in the three smaller triangles into which a large triangle can be split by drawing lines from a point inside the large triangle to each of the corners of the triangle. (编辑)我忘记了方法的名称(如果我知道的话)但是,多亏了@Floris,在三角形中插值的好方法称为重心插值 ,它根据区域的比率找到插值在三个较小的三角形中,可以通过从大三角形内的点到三角形的每个角绘制线来分割大三角形。 The area of each small triangle can be found from the length of each side of the triangle using Heron's formula . 每个小三角形的面积可以使用Heron公式从三角形每边的长度找到。

If speed improvements were needed, I think they could be obtained mainly from finding a quick way to find the triangle that contains the interpolation point but I'd want to profile some test runs before choosing which bits of the code to optimise. 如果需要提高速度,我认为它们主要是通过快速找到包含插值点的三角形来获得的,但是我想在选择要优化的代码位之前对一些测试运行进行分析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM