Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 数值微分:错误行为与预期不符_Python_Numeric_Numerical Methods - Fatal编程技术网

Python 数值微分:错误行为与预期不符

Python 数值微分:错误行为与预期不符,python,numeric,numerical-methods,Python,Numeric,Numerical Methods,我想用差商来区分函数fx,y相对于x和y的数值 def dfdx_v2(x, y, h): return 0.5 * (f(x+h, y) - f(x-h, y)) / h def dfdy_v2(x, y, h): return 0.5 * (f(x, y+h) - f(x, y-h)) / h 其中h是间隔的长度。在我的假设中,h越小,上面的实现应该越精确。然而,我注意到情况并非如此。当我绘制h=[1e-12,1e-4]的错误时,我得到以下图表: 我本以为,如果我让h为

我想用差商来区分函数fx,y相对于x和y的数值

def dfdx_v2(x, y, h):
    return 0.5 * (f(x+h, y) - f(x-h, y)) / h


def dfdy_v2(x, y, h):
    return 0.5 * (f(x, y+h) - f(x, y-h)) / h
其中h是间隔的长度。在我的假设中,h越小,上面的实现应该越精确。然而,我注意到情况并非如此。当我绘制h=[1e-12,1e-4]的错误时,我得到以下图表:

我本以为,如果我让h为零,误差会越来越小。然而,对于非常小的h,误差显著增加。另一个有趣的观察是误差振荡非常强烈的区域。为什么会这样?我原以为,误差是一个单调递增函数,没有任何波动。有没有办法解释为什么错误会这样

下面是我用来生成上图的代码:

import numpy as np
import matplotlib.pyplot as plt


def f(x, y):
    return x * x + y * x + x * y**2 + np.exp(x) + np.sin(x) * np.cos(x) + np.sin(y)


def dfdx_v1(x, y):
    return 2 * x + y + y**2 + np.exp(x) + np.cos(x)**2 - np.sin(x)**2


def dfdy_v1(x, y):
    return x + 2 * x * y + np.cos(y)


def dfdx_v2(x, y, h):
    return 0.5 * (f(x+h, y) - f(x-h, y)) / h


def dfdy_v2(x, y, h):
    return 0.5 * (f(x, y+h) - f(x, y-h)) / h


def main():
    x = 2.1415
    y = -1.1415

    h_min = 1e-12
    h_max = 1e-4
    n_steps = 10000

    h = np.linspace(h_min, h_max, n_steps)

    error = list()

    for i in range(n_steps):
        error.append(np.sqrt((dfdx_v1(x, y) - dfdx_v2(x, y, h[i]))**2 + (dfdx_v1(x, y) - dfdx_v2(x, y, h[i]))**2))

    plt.plot(h, error, linewidth=0.2, label="Error")
    plt.yscale("log")
    plt.legend()
    plt.show()


if __name__ == "__main__":
    main()

误差不是单调递增的事实是一个已知的数值微分问题。看

基本上,当步骤h变得太小时,由于存在数值误差,诸如fx+h、y-fx-h、y之类的表达式无法正确计算。 这是因为计算机采用有限精度算法,因此计算fx+h,y和fx-h,y误差很小。 减去两个非常接近的数字,其中fx+h,y和fx-h,y代表足够小的h,通常会给出一个由误差控制的结果。
除以h不会修正现有的误差。

误差不是单调递增的事实是已知的数值微分问题。看

基本上,当步骤h变得太小时,由于存在数值误差,诸如fx+h、y-fx-h、y之类的表达式无法正确计算。 这是因为计算机采用有限精度算法,因此计算fx+h,y和fx-h,y误差很小。 减去两个非常接近的数字,其中fx+h,y和fx-h,y代表足够小的h,通常会给出一个由误差控制的结果。
除以h不会纠正现有错误。

这与Python或大多数其他编程语言中浮点的精度有关。当h趋于零时,fx,y+h和fx,y-h之间的差值也趋于零时,但是,后者不会同样平滑。根据参数的精确值,差异有时会稍微大一点,有时会小一点


由于数字较大,dfdy_v2中的误差将大于h中的误差。因此,误差的指数将更大。当h接近零时,由于f的量化和严格增加的误差,这将导致波动。

这与Python或大多数其他编程语言中浮点的精度有关。当h趋于零时,fx,y+h和fx,y-h之间的差值也趋于零时,但是,后者不会同样平滑。根据参数的精确值,差异有时会稍微大一点,有时会小一点

由于数字较大,dfdy_v2中的误差将大于h中的误差。因此,误差的指数将更大。当h接近零时,由于f的量化和严格增加的误差,这都会导致波纹