【问题标题】:Lagrange interpolation in PythonPython中的拉格朗日插值
【发布时间】:2010-10-23 11:45:11
【问题描述】:

我想用拉格朗日方法插值多项式,但这段代码不起作用:

def interpolate(x_values, y_values):
    def _basis(j):
        p = [(x - x_values[m])/(x_values[j] - x_values[m]) for m in xrange(k + 1) if m != j]
        return reduce(operator.mul, p)

    assert len(x_values) != 0 and (len(x_values) == len(y_values)), 'x and y cannot be empty and must have the same length'

    k = len(x_values)
    return sum(_basis(j) for j in xrange(k))

我关注了Wikipedia,但是当我运行它时,我在第 3 行收到了 IndexError!

谢谢

【问题讨论】:

  • 如果反对者能解释反对意见,我将不胜感激......

标签: python interpolation polynomial-math


【解决方案1】:

试试

def interpolate(x, x_values, y_values):
    def _basis(j):
        p = [(x - x_values[m])/(x_values[j] - x_values[m]) for m in xrange(k) if m != j]
        return reduce(operator.mul, p)
    assert len(x_values) != 0 and (len(x_values) == len(y_values)), 'x and y cannot be empty and must have the same length'
    k = len(x_values)
    return sum(_basis(j)*y_values[j] for j in xrange(k))

您可以通过以下方式确认:

>>> interpolate(1,[1,2,4],[1,0,2])
1.0
>>> interpolate(2,[1,2,4],[1,0,2])
0.0
>>> interpolate(4,[1,2,4],[1,0,2])
2.0
>>> interpolate(3,[1,2,4],[1,0,2])
0.33333333333333331

所以结果是基于通过给定点的多项式的插值。在这种情况下,这 3 个点定义了一条抛物线,前 3 个测试表明,对于给定的 x_value,返回了规定的 y_value。

【讨论】:

  • 要让它在 python3 中工作:pip3 install future 然后你可以添加代码:from past.builtins import reduce, xrange; import operator
【解决方案2】:

我迟到了将近十年,但我发现这是在寻找拉格朗日插值的简单实现。 @smichr 的回答很好,但是 Python 有点过时了,我还想要一些可以很好地与 np.ndarrays 配合使用的东西,这样我就可以轻松地进行绘图。也许其他人会觉得这很有用:

import numpy as np
import matplotlib.pyplot as plt


class LagrangePoly:

    def __init__(self, X, Y):
        self.n = len(X)
        self.X = np.array(X)
        self.Y = np.array(Y)

    def basis(self, x, j):
        b = [(x - self.X[m]) / (self.X[j] - self.X[m])
             for m in range(self.n) if m != j]
        return np.prod(b, axis=0) * self.Y[j]

    def interpolate(self, x):
        b = [self.basis(x, j) for j in range(self.n)]
        return np.sum(b, axis=0)


X  = [-9, -4, -1, 7]
Y  = [5, 2, -2, 9]

plt.scatter(X, Y, c='k')

lp = LagrangePoly(X, Y)

xx = np.arange(-100, 100) / 10

plt.plot(xx, lp.basis(xx, 0))
plt.plot(xx, lp.basis(xx, 1))
plt.plot(xx, lp.basis(xx, 2))
plt.plot(xx, lp.basis(xx, 3))
plt.plot(xx, lp.interpolate(xx), linestyle=':')
plt.show()

【讨论】:

【解决方案3】:

检查索引,维基百科说“k+1 个数据点”,但如果你完全按照公式,你将设置 k = len(x_values) 应该是 k = len(x_values) - 1。

【讨论】:

  • 好的,为什么如果我这样做:interpolate([1, 2, 3], [1, 4, 9]) 它会返回 -0.5x^2 + 1.5x?看看这个:i.imgur.com/MkATz.gif
  • @rubik:抱歉,如果不知道插值算法,我无法帮助您解决这样一个特定问题(我不会阅读它)。再次检查您的逻辑或搜索现有实现。如果您发布更多关于如何应用插值的代码(例如,您的问题中缺少 x 的定义/初始值),那么有人可能会进一步帮助您。
  • 我正在使用 pypol (pypol.altervista.org) 并且 x 是单项式 (x=1) (pypol.altervista.org/functions.html#pypol.monomial)
【解决方案4】:

此代码与Python 3兼容:

def Lagrange (Lx, Ly):
    x=sympy.symbols('x')
    if  len(Lx)!= len(Ly):
        return 1
    y=0
    for k in range ( len(Lx) ):
        t=1
        for j in range ( len(Lx) ):
            if j != k:
                t=t* ( (x-Lx[j]) /(Lx[k]-Lx[j]) )
        y+= t*Ly[k]
    return y

【讨论】:

    猜你喜欢
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 1970-01-01
    相关资源
    最近更新 更多