跳转到内容

算法实现/数学/多项式插值

来自维基教科书,开放的书籍,开放的世界

拉格朗日插值是一种算法,它返回通过给定点集 (xi, yi) 的最小次数多项式。

给定 n 个点 (x0, y0), ..., (xn-1, yn-1),计算拉格朗日插值多项式 。请注意,总和中的 ith 项, 被构造为,当 xj 替换为 x 时,只要 ji,其值为零,而只要 j = i,其值为 yj。由此产生的拉格朗日插值多项式是这些项的总和,因此对于每个指定点 (xj, yj),其值均为 p(xj) = 0 + 0 + ... + yj + ... + 0 = yj

在下面的伪代码和每个实现中,多项式 p(x) = a0 + a1x + a2x2 + ... + an-1xn-1 表示为其系数数组,(a0, a1, a2, ..., an-1)

伪代码

[编辑 | 编辑源代码]
algorithm lagrange-interpolate is
    input: points (x0, y0), ..., (xn-1, yn-1) 
    output: Polynomial p such that p(x) passes through the input points and is of minimal degree

    for each point (xi, yi) do
        compute tmp := 
        compute term := tmp*          

    return p, the sum of the values of term

在下面的示例实现中,多项式 p(x) = a0 + a1x + a2x2 + ... + an-1xn-1 表示为其系数数组,(a0, a1, a2, ..., an-1)

虽然代码被编写为期望从实数(即浮点数)中获取点,并返回一个具有实数系数的多项式,但这个基本算法可以被调整为使用来自任何域(例如复数、模素数的整数或有限域)的输入和多项式系数。

#include <stdio.h>
#include <stdlib.h>

// input: numpts, xval, yval
// output: thepoly
void interpolate(int numpts, const float xval[restrict numpts], const float yval[restrict numpts],
    float thepoly[numpts])
{
    float theterm[numpts];
    float prod;
    int i, j, k;
    for (i = 0; i < numpts; i++)
        thepoly[i] = 0.0;
    for (i = 0; i < numpts; i++) {
        prod = 1.0;
        for (j = 0; j < numpts; j++) {
            theterm[j] = 0.0;
        };
        // Compute Prod_{j != i} (x_i - x_j)
        for (j = 0; j < numpts; j++) {
            if (i == j)
                continue;
            prod *= (xval[i] - xval[j]);
        };
        // Compute y_i/Prod_{j != i} (x_i - x_j)
        prod = yval[i] / prod;
        theterm[0] = prod;
        // Compute theterm := prod*Prod_{j != i} (x - x_j)
        for (j = 0; j < numpts; j++) {
            if (i == j)
                continue;
            for (k = numpts - 1; k > 0; k--) {
                theterm[k] += theterm[k - 1];
                theterm[k - 1] *= (-xval[j]);
            };
        };
        // thepoly += theterm (as coeff vectors)
        for (j = 0; j < numpts; j++) {
            thepoly[j] += theterm[j];
        };
    };
}
from typing import Tuple, List

def interpolate(inpts: List[Tuple[float, float]]) -> List[float]:
    n = len(inpts)
    thepoly = n * [0.0]
    for i in range(n):
        prod = 1.0
        # Compute Prod_{j != i} (x_i - x_j)
        for j in (j for j in range(n) if (j != i)):
            prod *= (inpts[i][0] - inpts[j][0])
        # Compute y_i/Prod_{j != i} (x_i - x_j)
        prod = inpts[i][1] / prod
        theterm = [prod] + (n - 1) * [0]
        # Compute theterm := prod*Prod_{j != i} (x - x_j)
        for j in (j for j in range(n) if (j != i)):
            for k in range(n - 1, 0, -1):
                theterm[k] += theterm[k - 1]
                theterm[k - 1] *= (-inpts[j][0])
        # thepoly += theterm
        for j in range(n):
            thepoly[j] += theterm[j]
    return thepoly
华夏公益教科书