用Matlab对离散数据进行高精度数值积分

计算科学 matlab 一体化 精确
2021-12-17 01:50:21

我有下面绘制的函数的离散数据: 使用 100k 点绘制的函数 “X = 1.57”附近的函数的“Y”值非常接近并且为零,例如 9.25558265263186E-11 和 5.92357284527227E-11。

直接使用“Trapz”函数,或间接使用“Integral”函数作为

f1 = griddedInterpolant(x,y); %I used also spline and other methods
f2 = @(t) f1(t);
Result = Integral(f2,0,pi/2)

失败,相对误差超过 30%。我可以为该函数提供更多数据点,但是,使用 100 个点或 100 万个点不会改变结果。

我的函数数据和参考解决方案来自通过多个长计算步骤计算的物理问题(解释起来很长)。由于我的代码和计算已经针对 *better 函数进行了验证,并且由于论文中报告了相同的问题(此设置开始出现奇点并且数值积分变得更加困难),我认为问题与数值积分,可能是因为 Matlab 的舍入误差和 16 位精度。

我还使用 VPA 进行了第一次模拟的所有计算。对于每一行代码,我至少使用了一次 VPA(在 Matlab 网站中,如果我理解正确,则写到如果其中一个数字/变量是 VPA,则该行中的整个计算都是使用更高的精度完成的)。我的意思是,我的数据(y 值)是在提供给 TRAPZ 函数之前使用 VPA 计算的。然后,我用

trapz(x,vpa(y))% y also has already been calculated using VPA. 

关于 X 值,我无法让它更高精度,我正在努力。

使用和不使用 VPA:使用 10 点和 Trapz,我得到:0.299517049200365,(我得到与上面解释的“积分”功能几乎相同。)使用 100k 点和 Trapz,我得到:0.299617122167918,参考解决方案是:0.220712757091533 .

我在另一个网站上写了同样的问题,人们使用我的数据(*for 100k)点,也得到了相同的结果(0.29...)。他们向我解释说,由于集成并没有发生这种 30% 的错误,它与我的数据和参考解决方案有关。有没有可能我们在这里错过了一些要点?

  • 在我的物理问题中,我可以更改一些参数,从而获得更好的功能(不是 x=1.57 附近的接近零值)。我的功能越是这样,我的错误就越多。

  • 100k_points.csv

1个回答

由于看起来您的离散函数是单调递减的,因此您可以使用左右黎曼和来计算数值积分的有效上限和下限。

有一种方法可以计算浮点数的准确总和,从而避免重复求和截断错误。我不知道 Matlab 是否有这个函数的实现,但是在 Python 中内置的math.fsum函数实现了这个。另一种替代实现是使用Kahan summation

使用精确的浮点求和,我计算了左右黎曼和:

import numpy
import math
data = numpy.loadtxt('100kPoints.csv', delimiter=',')
x = data[:,0]
y = data[:,1]
dx = x[1:] - x[:-1]
left_area = y[:-1] * dx
right_area = y[1:] * dx
left_int = math.fsum(left_area)
right_int = math.fsum(right_area)

这给出了数值积分误差的界限:

min value: 0.2996090880138866
max value: 0.29962515632195036
delta: 1.6068308063887926e-05

从这些结果以及 trapz 甚至 simps 产生的结果来看,我认为可以肯定地说数值积分至少精确到 4 位数,所以问题在于您的模拟计算曲线或您如何计算预期积分价值。