在本章介绍一下数值分析里的插值法,分为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 插值法
下次再写