插值法 数值分析

在本章介绍一下数值分析里的插值法,分为Lagrange插值和Newton插值。
引述:在很多时候我们都会遇到这样类似的问题,飞机失事后将会坠落在哪里,卫星太空飞船返航会坠落在哪里,,等等类似的问题。将其抽象成数学问题,就是已知N个座标对,形如(x1,y1),(x2,y2),,,,(xn,yn)要推算出后面或中间的点对位置,这就需要我们构造一个近似的函数来逼近原函数,使得近似函数经过或逼近那n个点。而数学上常用多项式来逼近原函数;(数学表达不是很恰当,大概意思明白即可)
具体的数学过程就不写了,有不清楚的地方可以去查一下,这里主要是代码。

1.Lagrange (拉格朗日)插值法

class Point{
    public String x;
    public String y;
}
class Point_cal{
    public double x;
    public double y;
}
public class Lagrange {//拉格朗日 插值法
    /*原理 * * 构造辅助函数Li(x) Li(x)有 Li(xi)=1,Li(x0),Li(x1),,,,其他不是i的=0; * 使得 pn(x)=L0(x)*y0+L1(x)*y1+....+Ln(x)*yn * 即Lk(xk)中除了xk不是零点,其他点为0点,Lk(x)=C*(x-x0)(x-x1).(x-xk)..(x-xn) C为常数。Lk(x)可以表示为这样,应为其他x代入为0, * 而 C可以通过 Lk(xk)=1确定,C=1/((xk-x0)(xk-x1)...(xk-xn)) * * * 优点,形式对称,算法简单。 * 缺点,每次循环都要从头开始,时间消耗大 f(x)为 原函数 pn(x)是近似函数 ωn(x)表示 x-xk 从k=0到 n的累乘 即(x-x0)(x-x1)...(x-xn)=ωn(x) * 误差分析:Rn(x)=f(x)-pn(x)=f(n+1次导数)(ξ)/(n+1)! *ωn(x); * * */

    public static void Constructor(Point data[]) {
        //这个函数是 print 抽象函数的
        String result="pn(x)=";
        for(int k=0;k<data.length;k++) {
            String coe="";
            for(int i=0;i<data.length;i++) {
                if(i==k) continue;
                coe+="(x-"+data[i].x+")/("+data[k].x+"-"+data[i].x+")*";    
            }
            coe=coe.substring(0,coe.length()-1);
            result+=coe+"*"+data[k].y+"+";
        }
        result=result.substring(0, result.length()-1);
        System.out.println(result);
    }

    public static void calculation(Point_cal data[],double newPoint_x) {
        //用于计算 出 新的点的函数值
        double result=0;
        for(int k=0;k<data.length;k++) {
            double coe=1;
            double fenzi=0,fenmu=0;
            for(int i=0;i<data.length;i++) {
                if(i==k) continue;
                fenzi=newPoint_x-data[i].x;fenmu=data[k].x-data[i].x;
                coe*=fenzi/fenmu;
            }

            result+=coe*data[k].y;
        }

        System.out.println(result);
    }

    public static void main(String[]args) {
        Point data[]=new Point[2];
        Point_cal data_cal[]=new Point_cal[2];
        for(int i=0;i<data.length;i++) {
            data[i]=new Point();
            data_cal[i]=new Point_cal();
            data[i].x="x"+i;
            data[i].y="y"+i;            
        }
        data_cal[0].x=1;data_cal[0].y=1.2;
        data_cal[1].x=2;data_cal[1].y=4.5;


        Constructor(data);
        calculation(data_cal,4);
    }

}

Newton 插值法

下次再写

点赞