三次样条插值法的C++程序实现(追赶法求解线性方程组)

三次样条插值法的C++程序实现(追赶法求解线性方程组)

求解线性方程组追赶法的程序为

double capway(int n,double nu[],double d[],double lan[],double h[],double x[],double y[], double t){
    double beita[n-1];
    beita[0]=lan[0]/2;
    for (int i=1;i<n-1;i++){
    	beita[i]=lan[i]/(2-nu[i-1]*beita[i-1]);
	}
    double yy[n];
    yy[0]=d[0]/2;
    for (int i=1;i<n;i++){
    yy[i]=(d[i]-nu[i-1]*yy[i-1])/(2-nu[i-1]*beita[i-1]);	
	}
	double xx[n];
	xx[n-1]=yy[n-1];
	for (int i=n-2;i>=0;i--){
		xx[i]=yy[i]-beita[i]*xx[i+1];
	}
	//上面求解线性方程组成功。
	}

计算线性方程组矩阵的程序为:

double spline(int n,double x[],double y[],int s,double x1,double xn,double t){
	//下面求hn的值;
   double h[n-1];
   for (int i=0;i<n-1;i++){
   	h[i]=x[i+1]-x[i];
   } 
	double aver[n-1];
	for (int i=0;i<n-1;i++){
	aver[i]=(y[i+1]-y[i])/h[i];		
	}
	//下面判断边界条件,第一类边界条件; 
    double lan[n-1];
    double d[n];
    double nu[n-1];
    if(s==1){
    	lan[0]=1;
    	d[0]=(6/h[0])*(aver[0]-x1);
    	nu[n-2]=1;
    	d[n-1]=(6/h[n-2])*(xn-aver[n-2]);
    	cout<<d[n-1]<<"\n";
	}
	if(s==2){
		lan[0]=0;
    	d[0]=2*x1;
    	nu[n-2]=0;
    	d[n-1]=2*xn;
	}
	//下面求nu;
	for (int i=0;i<n-2;i++){
		nu[i]=h[i]/(h[i]+h[i+1]);
	}
	for (int i=1;i<n-1;i++){
		lan[i]=h[i]/(h[i-1]+h[i]);
	}
	for (int i=1;i<n-1;i++){
		d[i]=6*(aver[i]-aver[i-1])/(h[i-1]+h[i]);
	}
	 double a[n][n];
	 for (int i=0;i<n;i++){
	 	a[i][i]=2;
	 }
	 for (int i=0;i<n-1;i++){
	 	a[i+1][i]=nu[i];
	 }
	 for (int i=0;i<n-1;i++){
	 	a[i][i+1]=lan[i];
	 }	
	 cout<<"输出线性方程组矩阵"<<"\n"; 
	 for (int i=0;i<n;i++){
	 	for (int j=0;j<n;j++){
	 	cout<<a[i][j]<<"     "; 	
		 }
		 cout<<"\n";
	 }
	 cout<<"输出线性方程组系数向量\n";
	 for (int i=0;i<n;i++){
	 	cout<<d[i]<<"  ";
	 }
	 cout<<"\n";
}

总的程序为

#include<iostream>
#include<cstdio> 
using namespace std;
//capway为用追赶发求解线性方程组; 
double capway(int n,double nu[],double d[],double lan[],double h[],double x[],double y[], double t){
    double beita[n-1];
    beita[0]=lan[0]/2;
    for (int i=1;i<n-1;i++){
    	beita[i]=lan[i]/(2-nu[i-1]*beita[i-1]);
	}
    double yy[n];
    yy[0]=d[0]/2;
    for (int i=1;i<n;i++){
    yy[i]=(d[i]-nu[i-1]*yy[i-1])/(2-nu[i-1]*beita[i-1]);	
	}
	double xx[n];
	xx[n-1]=yy[n-1];
	for (int i=n-2;i>=0;i--){
		xx[i]=yy[i]-beita[i]*xx[i+1];
	}
	//上面求解线性方程组成功。
	int as;
	for (int i=0;i<n;i++){
		if(t>=x[i]){
			as=i;
		}
	} 
	//下面计算函数值;
	if(as!=n-1){
	double numble;
	double sum1;
	double sum2;
	double sum3;
	double sum4;
	sum1=xx[as]*(x[as+1]-t)*(x[as+1]-t)*(x[as+1]-t)/6/h[as];
	sum2=xx[as+1]*(t-x[as])*(t-x[as])*(t-x[as])/6/h[as];
	sum3=(y[as]-xx[as]*h[as]*h[as]/6)*(x[as+1]-t)/h[as];
	sum4=(y[as+1]-xx[as+1]*h[as]*h[as]/6)*(t-x[as])/h[as];
	numble=sum1+sum2+sum3+sum4;
    cout<<t<<"的三次样条插值为"; 
	printf("%f",numble);
	}
}
double spline(int n,double x[],double y[],int s,double x1,double xn,double t){
	//下面求hn的值;
   double h[n-1];
   for (int i=0;i<n-1;i++){
   	h[i]=x[i+1]-x[i];
   } 
	double aver[n-1];
	for (int i=0;i<n-1;i++){
	aver[i]=(y[i+1]-y[i])/h[i];		
	}
	//下面判断边界条件,第一类边界条件; 
    double lan[n-1];
    double d[n];
    double nu[n-1];
    if(s==1){
    	lan[0]=1;
    	d[0]=(6/h[0])*(aver[0]-x1);
    	nu[n-2]=1;
    	d[n-1]=(6/h[n-2])*(xn-aver[n-2]);
    	cout<<d[n-1]<<"\n";
	}
	if(s==2){
		lan[0]=0;
    	d[0]=2*x1;
    	nu[n-2]=0;
    	d[n-1]=2*xn;
	}
	//下面求nu;
	for (int i=0;i<n-2;i++){
		nu[i]=h[i]/(h[i]+h[i+1]);
	}
	for (int i=1;i<n-1;i++){
		lan[i]=h[i]/(h[i-1]+h[i]);
	}
	for (int i=1;i<n-1;i++){
		d[i]=6*(aver[i]-aver[i-1])/(h[i-1]+h[i]);
	}
	 double a[n][n];
	 for (int i=0;i<n;i++){
	 	a[i][i]=2;
	 }
	 for (int i=0;i<n-1;i++){
	 	a[i+1][i]=nu[i];
	 }
	 for (int i=0;i<n-1;i++){
	 	a[i][i+1]=lan[i];
	 }	
	 cout<<"输出线性方程组矩阵"<<"\n"; 
	 for (int i=0;i<n;i++){
	 	for (int j=0;j<n;j++){
	 	cout<<a[i][j]<<"     "; 	
		 }
		 cout<<"\n";
	 }
	 cout<<"输出线性方程组系数向量\n";
	 for (int i=0;i<n;i++){
	 	cout<<d[i]<<"  ";
	 }
	 cout<<"\n";
    capway(n,nu,d,lan,h,x,y,t);
}
int main(){
    int num;
    cout<<"输入节点的个数:"; 
    scanf("%d",&num);
    double x[num],y[num];
    for (int i=0;i<num;i++){
    	cout<<"输入第"<<i+1<<"个x的值:"; 
	    scanf("%lf",&x[i]);
		cout<<"输入第"<<i+1<<"个y的值:";
		scanf("%lf",&y[i]);
	}
	printf("输入边界条件,如果输入1,表示第一类边界条件,2表示第二类边界条件");
	int s;
	cin>>s; 
	double x1,xn; 
	printf("输入边界条件值\n");
	cout<<"输入左端边界条件值:";
	cin>>x1;
	cout<<"输入右端边界条件值:";
	cin>>xn; 
	printf("输入要计算的函数值:"); 
	double t;
	cin>>t;
	spline(num,x,y,s,x1,xn,t);
	return 0;  
}

运行结果如下:
在这里插入图片描述

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是使用C++实现三次样条插值的示例代码: ```c++ #include <iostream> #include <vector> using namespace std; // 定义三次样条插值的数据结构 struct SplineData { vector<double> a, b, c, d, x; int n; SplineData(const vector<double>& x, const vector<double>& y) { n = x.size(); vector<double> h(n - 1), A(n - 2), B(n - 2), C(n - 2), F(n - 2); // 计算每一段的差值h for (int i = 0; i < n - 1; i++) { h[i] = x[i + 1] - x[i]; } // 构造三对角线性方程组 for (int i = 1; i < n - 1; i++) { A[i - 1] = h[i - 1]; B[i - 1] = 2 * (h[i - 1] + h[i]); C[i - 1] = h[i]; F[i - 1] = 3 * ((y[i + 1] - y[i]) / h[i] - (y[i] - y[i - 1]) / h[i - 1]); } // 解三对角线性方程组 vector<double> P(n); vector<double> Q(n - 1); vector<double> S(n - 1); vector<double> R(n - 1); P[0] = 0; P[n - 1] = 0; for (int i = 0; i < n - 2; i++) { double t = A[i] / B[i]; B[i + 1] = B[i + 1] - t * C[i]; F[i + 1] = F[i + 1] - t * F[i]; } Q[0] = F[0] / B[0]; S[n - 2] = F[n - 3] / B[n - 3]; for (int i = n - 4; i >= 0; i--) { Q[n - i - 2] = (F[i] - C[i] * Q[n - i - 3]) / B[i]; R[n - i - 2] = (A[i] * Q[n - i - 3] + C[i] * Q[n - i - 2] - F[i]) / B[i + 1]; S[i] = S[i + 1] + R[n - i - 2]; } // 计算插值函数的系数 for (int i = 0; i < n - 1; i++) { double ai = y[i]; double bi = (y[i + 1] - y[i]) / h[i] - h[i] * (S[i + 1] + 2 * Q[i]) / 3; double ci = S[i]; double di = (S[i + 1] - S[i]) / (3 * h[i]); this->a.push_back(ai); this->b.push_back(bi); this->c.push_back(ci); this->d.push_back(di); this->x.push_back(x[i]); } } // 根据插值函数的系数计算插值函数在x_val处的值 double evaluate(double x_val) const { int i = 0; while (i < n - 1 && x_val > x[i + 1]) { i++; } double dx = x_val - x[i]; double result = a[i] + dx * (b[i] + dx * (c[i] + dx * d[i])); return result; } }; int main() { vector<double> x = {0, 1, 2, 3, 4, 5, 6}; vector<double> y = {1, 0, 1, 0, 1, 0, 1}; SplineData data(x, y); for (double x_val = 0; x_val <= 6; x_val += 0.5) { cout << "f(" << x_val << ") = " << data.evaluate(x_val) << endl; } return 0; } ``` 在上述代码中,我们首先定义了一个名为`SplineData`的结构体,用于存储三次样条插值的数据。在结构体的构造函数中,我们首先计算每一段的差值`h`,然后构造三对角线性方程组并解方程,最后计算插值函数的系数`a`、`b`、`c`、`d`。在`evaluate`函数中,我们根据插值函数的系数计算插值函数在`x_val`处的值。 在主函数中,我们定义了一个名为`data`的`SplineData`对象,并使用样例数据对其进行初始化。接下来,我们使用`evaluate`函数计算插值函数在`[0, 6]`范围内每隔`0.5`个单位的值,并输出结果。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值