无法构造向后牛顿多项式

时间:2019-10-05 00:50:19

标签: python python-3.x numpy numerical-methods

我已经使用此代码半天了,我最多只能更改曲线的方向。我尝试使用相同的算法构造正向牛顿多项式(尽管由于方向反转而略有调整),但效果很好。我将它们都包括在内供您比较。


import numpy as np
import matplotlib.pyplot as plt

a = -1
b = 1
N = 201
x = np.linspace(a, b, N)
n = [3, 7, 10, 20]

plotsPfw = [None, None, None, None]
fig1, ((plotsPfw[0], plotsPfw[1]),(plotsPfw[2], plotsPfw[3])) = plt.subplots(2,2, gridspec_kw = {'hspace': 0.5, 'wspace': 0.5})
plotsPbw = [None, None, None, None]
fig2, ((plotsPbw[0], plotsPbw[1]),(plotsPbw[2], plotsPbw[3])) = plt.subplots(2,2, gridspec_kw = {'hspace': 0.5, 'wspace': 0.5})

def Runge(x):
    return 1/(1+25*np.power(x,2))

def findif_forw(func, order, i):
    if order == 1:
        return (func[i+1] - func[i])
    else:
        return (findif_forw(func, order-1, i+1) - findif_forw(func, order-1, i))

def findif_backw(func, order, i):
    if order == 1:
        return (func[-1-i] - func[-1-i+1])
    else:
        return (findif_backw(func, order-1, i) - findif_backw(func, order-1, i-1))

def Newton_forw(xi, func, n):
    h = xi[1] - xi[0]
    N = func[0]
    q = (x - xi[0])/h
    Q = 1
    for i in range(1, n):
        Q *= (q - i + 1)/i
        N += findif_forw(func, i, 0)*Q
    return N

def Newton_backw(xi, func, n):
    h = xi[1] - xi[0]
    N = func[-1]
    q = (x - xi[-1])/h
    Q = 1
    for i in range(1, n):
        Q *= (q + i - 1)/i
        N += findif_backw(func, i, i)*Q
    return N

yRunge = Runge(x)

for i in range(0, len(n)):
    xi = np.linspace(a,b,n[i])
    yRungei = Runge(xi)
    yNewton_forw = Newton_forw(xi, yRungei, n[i])
    yNewton_backw = Newton_backw(xi, yRungei, n[i])
    plotsPfw[i].plot(x, yRunge, ':r', x, yNewton_forw, '-g', linewidth = 0.25)
    plotsPfw[i].set_title('n = {}'.format(n[i]))
    plotsPfw[i].set_xlabel('x')
    plotsPfw[i].set_ylabel('Runge, fwd P_{}(x)'.format(n[i]))
    plotsPbw[i].plot(x, yRunge, ':r', x, yNewton_backw, '-b', linewidth = 0.25)
    plotsPbw[i].set_title('n = {}'.format(n[i]))
    plotsPbw[i].set_xlabel('x')
    plotsPbw[i].set_ylabel('Runge, bkwd P_{}(x)'.format(n[i]))

plt.show()

有限的差异似乎还不错,在我手动检查它们之后,问题可能出在多项式的q部分。这对于情况n = 3最为明显-在步骤1之后的正向公式中Q是上升(沿插值方向)斜率,在步骤2 Q之后是向下的抛物线偏移在最左边,所以它们似乎在某种程度上相互抵消,导致插值多项式图经过目标图n次。

在后向公式中,Q几乎总是下降(再次沿插值方向),因此最左端变得极不平衡,这可以在图形上看到。我尝试了以下方法:

  • 反转1阶有限差分返回的值的符号

  • 反转q的公式符号

  • 在Q多项式中使用q + i + 1,q + i,q-i + 1

我认为,要么插值方法被假定为朝着另一端变得不平衡(并且正向多项式是错误的),要么正向多项式的行为符合预期(反向多项式是错误的)。

1 个答案:

答案 0 :(得分:0)

您的后向差异非常奇怪。为什么在-i中存在1阶差?您可以修复该错误,并通过将它们的顺序终止于0来

,从而进一步简化这两个过程
def findif_forw(func, order, i):
    return  func[i] if order == 0 else findif_forw(func, order-1, i+1) - findif_forw(func, order-1, i);

def findif_backw(func, order, i):
    return  func[i] if order == 0 else findif_backw(func, order-1, i) - findif_backw(func, order-1, i-1)

这将使用初始索引中的值计算向后差异 向后order个词。要使它成为数组末尾的值,只需用

对其进行调用
        N += findif_backw(func, i, -1)*Q

请注意,这在重新计算几个中间差异时不是很有效。

从功能的对称性可以预期的结果,前后结果相同。 enter image description here