日期:2014-05-20  浏览次数:20743 次

三次样条差值
下面是要求三次样条插值的题目。
对给定的三个数据点(-2,-27),(0,-1),(1,0) 
(a)构造三次自然样条插值 
(b)画出三次自然样条及给定的数据点的图形,画出三次自然样条的一阶、二阶导数图形,验证三次自然样条的性质。 

下面是我的代码:

public class CSI {

/**
* @param args
*/
static int maxindex(double a[],int n){
int maxindex=0;
for(int i=1;i<n;i++){
if(Math.abs(a[i])>Math.abs(a[maxindex]))
maxindex=i;
}
return maxindex;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
double[] t={-2,0,1};
double[] y={-27,-1,0};
//double α1,α2,α3,α4,β1,β2,β3,β4;
double[] x=new double[8];
double[] b={y[0],y[1],y[1],y[2],0,0,0,0};
double t12,t13,t22,t23,t32,t33;
t12=t[0]*t[0];t13=t12*t[0];
t22=t[1]*t[1];t23=t22*t[1];
t32=t[2]*t[2];t33=t32*t[2];

double [][] A= {
{1,t[0],t12,t13,0,0,0,0},
{1,t[1],t22,t23,0,0,0,0},
{0,0,0,0,1,t[1],t22,t23},
{0,0,0,0,1,t[2],t32,t33},
{0,1,2*t[1],3*t22,0,-1,-2*t[1],-3*t22},
{0,0,2,6*t[1],0,0,-2,-6*t[1]},
{0,0,2,6*t[0],0,0,0,0},
{0,0,0,0,0,0,2,6*t[2]}};

/*//输出A知A输入正确
for(int i=0;i<8;i++){
for(int j=0;j<8;j++) 
System.out.print(A[i][j]+" ");
System.out.println(); 
}*/

//下面开始待选主元的高斯消元回代解方程组
double[][] M=new double[8][8];
double [] temp=new double[8];
double[] w=new double[8];
for(int k=0;k<7;k++){ 
for (int i=0;i<8;i++) 
w[i]=A[i][k];
for(int i=0;i<k;i++){
w[i]=0;

int p=maxindex(w,8); 
if(p!=k){
//交换第P行和第K行 
for(int i=0;i<8;i++){
temp[i]=A[p][i];
A[p][i]=A[k][i];
A[k][i]=temp[i];
}
//经shiyan.class单独测试该选主元算法是正确的 
}
//高斯消元
if(A[k][k]==0)continue;
for(int i=k+1;i<8;i++){
M[i][k]=A[i][k]/A[k][k];
}
for(int j=k+1;j<8;j++){
b[j]=b[j]-M[j][k]*b[k];
for(int i=k+1;i<8;i++){
A[i][j]=A[i][j]-M[i][k]*A[k][j];

}  
}
//回代求解
for(int j=7;j>=0;j--){
if(A[j][j]==0)break;
x[j]=b[j]/A[j][j];
for(int i=0;i<=j-1;i++){
b[i]=b[i]-A[i][j]*x[j]; 
}
}
System.out.println("解是:");
for(int i=0;i<8;i++){
System.out.print(x[i]+" ");
}
System.out.println();

}

}

但我的输出解老是错误的。
正确的结果应该是:
-1.0
5.0
-6.0
-1.0
-1.0
4.999999999999999
-6.000000000000001
2.0000000000000004

看了很久代码,没检查出错误来,也和别人得比较过,没感觉自己的错误。但结果就是错的,嘿嘿。望哪位大侠给指出错误呗。

------解决方案--------------------
学习下~