Java下实现重心拉格朗日插值法

1.拉格朗日插值法简介(引自维基百科)

对某个多项式函数,已知有给定的k + 1个取值点:

(x_{0},y_{0}),\ldots ,(x_{k},y_{k})

 

其中对应着自变量的位置,而y_{j}对应着函数在这个位置的取值。

假设任意两个不同的xj都互不相同,那么应用拉格朗日插值公式所得到的拉格朗日插值多项式为:

其中每个\ell _{j}(x)拉格朗日基本多项式(或称插值基函数),其表达式为:

\ell _{j}(x):=\prod _{​{i=0,\,i\neq j}}^{​{k}}{\frac  {x-x_{i}}{x_{j}-x_{i}}}={\frac  {(x-x_{0})}{(x_{j}-x_{0})}}\cdots {\frac  {(x-x_{​{j-1}})}{(x_{j}-x_{​{j-1}})}}{\frac  {(x-x_{​{j+1}})}{(x_{j}-x_{​{j+1}})}}\cdots {\frac  {(x-x_{​{k}})}{(x_{j}-x_{​{k}})}}. 

2.重心拉格朗日插值法

重心拉格朗日插值法是拉格朗日插值法的一种改进。

其基本多项式可重新写为:

定义重心权w_{j}={\frac  {1}{\prod _{​{i=0,i\neq j}}^{k}(x_{j}-x_{i})}},可将基本多项式改写为:

L(x)=\ell (x)\sum _{​{j=0}}^{k}{\frac  {w_{j}}{x-x_{j}}}y_{j}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (1)

经过Jean-Paul Berrut, Lloyd N. Trefethen 所给出的一系列推导可将L(x)改写为:

L(x)={\frac  {\sum _{​{j=0}}^{k}{\frac  {w_{j}}{x-x_{j}}}y_{j}}{\sum _{​{j=0}}^{k}{\frac  {w_{j}}{x-x_{j}}}}}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (2)

该公式被称作“真正的”重心拉格朗日插值公式,主要是为了与推导过程中由简化的基本多项式构成的公式相区分。该式相比一般的拉格朗日插值公式更易于计算,改变插值点的数量不需要重新计算,算法的复杂度降低了一个量级。

3.Java代码

简单的Java代码,可能存在潜在的错误。

 

    import java.util.Scanner;

public class BarycentricLagrangeInterpolation {
    private static double[] BELIE(double x[],double y[],double x0[]) {
        int m = x.length;
        int n = x0.length;
        double y0[] = new double[n];
        for(int yi = 0;yi < n;yi ++) {
            double j = 0,k = 0,l = 0;
            int ic = 0;
            for(int ia = 0;ia < m;ia ++) {
                double w = 1;
                for(int ib = 0;ib < m;ib ++) {
                    if(ia != ib) w /= (x[ia] - x[ib]);
                }
                System.out.println(w);
                k += (w / ((x0[yi] - x[ic]))) * y[ic];
                l += (w / ((x0[yi] - x[ic])));
                ic ++ ;
                j = k / l;
            }
            y0[yi] = j;
        }
        return y0;
    }

    public static void main(String[] args) {
        System.out.println("请输入给定的插值点数量:");
        Scanner input = new Scanner(System.in);
        int m = input.nextInt();
        System.out.println("请输入需求解的插值点数量:");
        int n = input.nextInt();
        double x[] = new double[m];
        double y[] = new double[m];
        double x0[] = new double[n];
        System.out.println("依次输入给定的插值点:");
        for(int i = 0;i < m;i ++){
            x[i] = input.nextDouble();
        }
        System.out.println("依次输入给定的插值点对应的函数值:");
        for(int i = 0;i < m;i ++){
            y[i] = input.nextDouble();
        }
        System.out.println("依次输入需求解的插值点");
        for(int i = 0;i < n;i ++){
            x0[i] = input.nextDouble();
        }
        double y0[] = BELIE(x, y, x0);
        System.out.println("运用重心拉格朗日插值法求解得:");
        for(int i = 0;i < n;i ++){
            System.out.println(y0[i] + " ");
        }
        System.out.println();
        input.close();
    }
}

 

 

 

①可见于people.maths.ox.ac.uk/trefethen/barycentric.pdf

 

 

转载于:https://www.cnblogs.com/PabloZeal/p/6686538.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值