1

我正在用 FORTRAN 77 编写一个模拟,其中我需要从一些实验数据中获取一个参数值。数据来自互联网数据库,所以我提前下载了它,但是没有简单的数学模型可以用来提供连续尺度的值——我只有离散的数据点。但是,对于 x 轴上的任何值,我都需要知道这个参数,而不仅仅是我从数据库中获得的离散值。

为简化起见,您可以说我知道 的f(x)所有整数值的值x,并且需要一种方法来找到f(x)任何实际x值(永远不会超出我所知道的最小或最大x)。

我的想法是获取数据并进行线性插值,以便能够获取参数值;在伪代码中:

double xd = largest_data_x_lower_than(x)

double slope = (f(xd+dx)-f(xd))/dx // dx is the distance between two x values
double xtra = x-xd

double fofx = f(xd)+slope*xtra

为了实现这一点,我需要对数据点进行某种查找。我可以xd通过从数据库中获取所有整数的值来轻松查找x,这样xd = int(x)dx = 1,但我仍然不知道如何实现查找f(xd)

什么是实现这一点的好方法?

在一次模拟运行期间,该值将被获取 10^7 到 10^9 次,因此性能至关重要。换句话说,每次我需要一个值时都从 IO 读取f(xd)不是一种选择。

我目前有一个文本文件中的数据点,每行有一对(制表符分隔)x,f(x),所以对于一个解决方案的奖励点,它还提供了一种将数据从那里获取到任何需要的形状的平滑方式。

4

3 回答 3

2

你说你有所有整数的值。你有从toi, f(i)的所有整数的对吗?然后将值读入一个维度为 的数组。除非值的数量是巨大的。对于 和 之间的实数值,很容易在数组中建立索引并在最近的一对数值之间进行插值。 iMNf(i)yM:NMN

为什么要使用 FORTRAN 77?Fortran 90/95/2003 已经使用我们多年了...

编辑:在评论中回答问题,重新如何在 FORTRAN 77 中只读取一次数据值,而不必在长链调用中将它们作为参数传递。技巧 1:在程序启动时,将它们读入数组,该数组位于一个命名的公共块中。技巧 2:第一次调用返回的函数时,将f(x)值读入同样位于SAVE语句中的局部变量。使用已保存的逻辑来指定函数是否在其第一次调用中。一般来说,我更喜欢技术 2,因为它更“本地”,但它不是线程安全的。如果您正在并行进行模拟,则第一种技术可以在程序进入多线程之前的启动阶段完成。

下面是一个使用示例SAVEfortran SAVE 语句。(在 Fortran 95 表示法中......转换为 FORTRAN 77)。将读取的数据放入IF块中的数组中。

于 2013-04-06T01:06:22.423 回答
0

您可能想要一种插入或拟合数据的方法,但您需要更具体地了解数据的维度、数据的行为方式、访问数据的方式(例如,也许您的下一个请求总是靠近最后一个),网格的制作方式(均匀分布,随机或其他方式),以及您需要数据的位置才能知道哪种方法最适合您。

但是,如果现有数据集非常密集且接近线性,那么您当然可以进行线性插值。

于 2013-04-05T22:59:35.977 回答
0

fvals使用您的数据库(文件),您可以创建一个带有fvals(ii)函数的数组f(xmin + (ii-1) * dx)。x 值xx和数组索引之间的映射是ii = floor((xx - xmin) / dx) + 1. 一旦你知道ii了,你就可以使用它周围的点进行插值:使用iiii+1或一些更高阶的多项式插值进行线性插值。对于后者,您可以使用来自Numerical Recipes的相应 polint 例程。请参见第 103 页。

于 2013-04-07T18:41:18.113 回答