数值计算 第三章.docx
《数值计算 第三章.docx》由会员分享,可在线阅读,更多相关《数值计算 第三章.docx(28页珍藏版)》请在冰豆网上搜索。
![数值计算 第三章.docx](https://file1.bdocx.com/fileroot1/2023-1/8/c15b7ba0-178b-4f03-8331-ca1716ab7b27/c15b7ba0-178b-4f03-8331-ca1716ab7b271.gif)
数值计算第三章
/*
*@author:
邓仕军
*@time:
2012-04-26
*Lagrange插值法
*/
publicclassProgram3_1{
privatedoubledata[][];
privateintsize;
publicProgram3_1(){
init();
}
publicProgram3_1(doubledata[][],intsize){
init(data,size);
}
voidinit(doubledata[][],intsize){
this.data=data;
this.size=size;
}
voidinit(){
this.data=newdouble[][]{};
this.size=0;
}
voidsetData(doubledata[][],intsize){
this.data=data;
this.size=size;
}
publicintgetSize(){
returnthis.size;
}
voidSetSize(intsize){
this.size=size;
}
publicdouble[][]getData(){
returnthis.data;
}
publicdoubleinterpolation(doublex){
doubletemp=1d;
doublesum=0d;
for(inti=0;ifor(intj=0;jif(i!
=j){
temp*=(x-data[j][0])/(data[i][0]-data[j][0]);
}
}
sum+=(temp*data[i][1]);
temp=1d;
}
returnsum;
}
publicvoidprint(){
System.out.print("X");
for(inti=0;iSystem.out.print(data[i][0]+"");
}
System.out.println();
System.out.print("y=f(x)");
for(inti=0;iSystem.out.print(data[i][1]+"");
}
System.out.println();
}
}//Program3_1
/*
*@author:
邓仕军
*@time:
2012-04-26
*Lagrange插值法测试
*/
publicclassTestProgram3_1{
publicstaticvoidmain(String[]args){
double[][]data=newdouble[][]{{144,12},{169,13},{225,15}};
Program3_1a=newProgram3_1(data,3);
a.print();
System.out.println("测试f(175)="+a.interpolation(175));
}
}
运行结果:
/**
*@author邓仕军
*@time2012-04-28
*@version0.1
*Newton插值法:
*此程序parameter是不必要的,因为完全可以在data这个二维数组中保存求得的a1,a2,...,an,
*但是这样也将data中的数据覆盖了,如果一旦后人需要这个数据(我们无法保证使用这个对象的
*人不会提出要使用data的要求),将回天无术。
因此,在本版本中我将使用一个parameter一维
*数组保存a1,a2,...,an,从而使得data中的数据得以保存下来,在下一个版本中,我将只使用
*data这个二维数组,实现同样的功能
*/
classProgram3_2{
privatedouble[][]data;//给定用来算均差的列表
privateintsize;//data值的对数
privatedouble[]parameter;//参数
publicProgram3_2(){
init();
}
publicProgram3_2(doubledata[][],intsize){
init(data,size);
}
voidinit(doubledata[][],intsize){
this.data=data;
this.size=size;
this.parameter=newdouble[size];
//求参数
for(inti=this.getSize()-1;i>=0;i--){
if(i==0){
this.parameter[0]=this.getData()[0][1];
}else{
this.parameter[i]=(this.getData()[i][1]-this.getData()[i-1][1])
/(this.getData()[i][0]-this.getData()[i-1][0]);
}
}
for(inti=2;ifor(intj=this.getSize()-1;j>=i;j--){
this.parameter[j]=(this.getParameter()[j]-this
.getParameter()[j-1])
/(this.getData()[j][0]-this.getData()[j-i][0]);
}
}
}
voidinit(){
this.data=newdouble[][]{};
this.size=0;
this.parameter=newdouble[size];
}
voidsetData(doubledata[][],intsize){
init(data,size);
}
publicintgetSize(){
returnthis.size;
}
publicdouble[][]getData(){
returnthis.data;
}
publicdouble[]getParameter(){
returnthis.parameter;
}
doublefunction(doublex){
doublesum=0d;
for(inti=this.getSize()-2;i>=1;i--){
if(i==this.getSize()-2){
sum+=((x-this.getData()[i-1][0])*this.getParameter()[i]+this
.getParameter()[i-1]);
}else{
sum*=(x-this.getData()[i-1][0]);
sum+=this.getParameter()[i-1];
}
}
returnsum;
}//function
publicvoidprint(){
//可以看到,证实因为data中数据得以保存,在这里实现打印这个函数式多么的方便
System.out.print("X");
for(inti=0;iSystem.out.print(data[i][0]+"");
}
System.out.println();
System.out.print("y=f(x)");
for(inti=0;iSystem.out.print(data[i][1]+"");
}
System.out.println();
}
}//Program3_2
/**
*@author邓仕军
*@time2012-04-28
*@version0.2
*Newton插值法:
不用parameter,仅仅使用data这个二维数组,保存系a1,a2...,an,这样确实节约了空间,
*但在后面如果需要使用data中数据,就非常不方便了.因此,我并不认为这是一种比版本0.1明智的做法
*/
classProgram3_2{
privatedouble[][]data;//给定用来算均差的列表
privateintsize;//data值的对数
publicProgram3_2(){
init();
}
publicProgram3_2(doubledata[][],intsize){
init(data,size);
}
voidinit(doubledata[][],intsize){
this.data=data;
this.size=size;
this.print();
//因为data中的数据会被破坏,因此print就只有放在这里,才能让用户看到正在本该属于data的数据
//(事实上现在的print函数也因为data的改变,并不能再提供我们所希望的打印功能)
//放在这里显然不符合面向对象理念,但在本程序中也没多大关系
for(inti=1;ifor(intj=this.getSize()-1;j>=i;j--){
this.data[j][1]=(this.data[j][1]-this.data[j-1][1])
/(this.data[j][0]-this.data[j-i][0]);
}
}
}
voidinit(){
this.data=newdouble[][]{};
this.size=0;
}
voidsetData(doubledata[][],intsize){
init(data,size);
}
publicintgetSize(){
returnthis.size;
}
publicdouble[][]getData(){
returnthis.data;
}
doublefunction(doublex){
doublesum=0d;
for(inti=this.getSize()-2;i>=1;i--){
if(i==this.getSize()-2){
sum+=((x-this.getData()[i-1][0])*this.getData()[i][1]+this
.getData()[i-1][1]);
}else{
sum*=(x-this.getData()[i-1][0]);
sum+=this.getData()[i-1][1];
}
}
returnsum;
}//function
publicvoidprint(){
System.out.print("X");
for(inti=0;iSystem.out.print(data[i][0]+"");
}
System.out.println();
System.out.print("y=f(x)");
for(inti=0;iSystem.out.print(data[i][1]+"");
}
System.out.println();
}
}//Program3_2
publicclassTestProgram3_2{
publicstaticvoidmain(String[]args){
double[][]data=newdouble[][]{{144,12},{169,13},{225,15}};
intsize=3;
Program3_2a=newProgram3_2(data,size);
System.out.println("测试f(175)="+a.function(175));
System.out.println("-----------------------------------");
data=newdouble[][]{{0.4,0.41075},{0.55,0.57815},{0.65,0.69675},{0.80,0.88811}};
size=4;
a.setData(data,size);
System.out.println("测试f(0.596)="+a.function(0.596));
System.out.println("-----------------------------------");
data=newdouble[][]{{0.80,0.88811},{0.90,1.02652},{1.05,1.25382}};
size=3;
a.setData(data,size);
System.out.println("测试f(0.955)="+a.function(0.955));
}
}
运行结果:
/*
*@author邓仕军
*@version0.1
*@time2012-05-03
*Hermite插值
*/
classHermite{
Derivativeder;//导数类
privatedouble[][]data;//传进来的数据
privateintsize;//data值的对数
privatedouble[]a_x;//α(x)
privatedouble[]b_x;//β(x)
privateintcount;
publicHermite(){
init();
}
publicHermite(doubledata[][],intsize){
init(data,size);
}
voidinit(){
this.data=newdouble[][]{};
this.size=0;
this.count=0;
this.a_x=newdouble[size];
this.b_x=newdouble[size];
try{
der=newDerivative(this,this.getClass().getDeclaredMethod("fX",
double.class));
}catch(NoSuchMethodException|SecurityExceptione){
e.printStackTrace();
}
}
voidinit(doubledata[][],intsize){
this.data=data;
this.count=0;
this.size=size;
this.a_x=newdouble[size];
this.b_x=newdouble[size];
try{
der=newDerivative(this,this.getClass().getDeclaredMethod("fX",
double.class));
}catch(NoSuchMethodException|SecurityExceptione){
e.printStackTrace();
}
}//init(....);
voidsetData(doubledata[][],intsize){
init(data,size);
}
publicintgetSize(){
returnthis.size;
}
publicdouble[][]getData(){
returnthis.data;
}
doublefunction(doublex){
doublesum=0d;
//求参数
for(inti=0;icount=i;//L(x)确定下标i
a_x[i]=(1-2*(x-this.getData()[i][0])
*der.getDerivative(this.getData()[i][0]))
*lX(i,x)*lX(i,x);
b_x[i]=(x-this.getData()[i][0])*lX(i,x)*lX(i,x);
}
//求值
for(inti=0;isum+=this.a_x[i]*this.getData()[i][1];
}
for(inti=0;isum+=this.b_x[i]*this.getData()[i][2];
}
returnsum;
}
/*
*被求导的函数
*/
doublefX(doublex){
returnlX(count,x);
}
/*
*L(X),k为下标
*/
doublelX(intk,doublex){
doublesum=1d;
for(inti=0;iif(i!
=k){
sum*=(x-data[i][0])/(data[k][0]-data[i][0]);
}
}
returnsum;
}
publicvoidprint(){
System.out.printf("%8s","i:
");
for(inti=0;iSystem.out.printf("%12s",i);
}
System.out
.println("\n----------------------------------------------------------------------------");
System.out.printf("%8s","X");
for(inti=0;iSystem.out.printf("%12.5f",data[i][0]);
}
System.out.println();
System.out.printf("%8s","y=f(x)");
for(inti=0;iSystem.out.printf("%12.5f",data[i][1]);
}
System.out.println();
System.out.printf("%8s","y=f'(x)");
for(inti=0;iSystem.out.printf("%12.5f",data[i][2]);
}
System.out.println();
System.out.printf("%8s","α(x)");
for(inti=0;iSystem.out.printf("%12.5f",a_x[i]);
}
System.out.println();
System.out.printf("%8s","β(x)");
for(inti=0;iSystem.out.printf("%12.5f",b_x[i]);
}
System.out.println();
}
}
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
/*
*@author邓仕军
*@version0.1
*@time2012-05-03
*Derivative:
求一个函数的导数,运用反射机制
*/
classDerivative{
Methodmethod;
Objectobj;
publicDerivative(Objectobj,Methodf){
this.method=f;
this.obj=obj;
}
strictfpdoublegetDerivative(doublex){
doublederiva1=0d,deriva2=0d;
booleanflag=true;
doubleDx=0.0001;//增量△X
finaldoubleprecision=