最小二乘法拟合多项式
求解
给定数据点(xi ,yi),用最小二乘法拟合数据的多项式,并求平方误差。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=1000;
int n,m;
double b[maxn];// Σxy
double a[maxn];// 多项式系数
double A[maxn][maxn];//求出 Σx^i
double sum_x[maxn];
double x[maxn][maxn];//x[i][j] 存储的是xj的第i次方
double y[maxn][maxn];//y[i][j] 存储的是y[j]*x[i];
//求x矩阵
void Print_1()
{
//输出用到的x次方 和x次方*y
for(int i=0;i<=2*m;i++){
cout<<"x "<<i<<" Sub square: ";
for(int j=0;j<n;j++)
printf("%.3lf ",x[i][j]);
printf("%.3lf ",sum_x[i]);
cout<<endl;
}
for(int i=0;i<=m;i++){
cout<<"x "<<i<<" Sub square * y : ";
for(int j=0;j<n;j++)
printf("%.3lf ",y[i][j]);
printf("%.3lf ",b[i]);
cout<<endl;
}
cout<<"Normal matrix"<<endl;
for(int i=0;i<=m;i++){
for(int j=0;j<=m+1;j++){
printf("%.3lf ",A[i][j]);//cout<<A[i][j]<<"\t";
}
cout<<endl;
}
}
void init()
{
//求所有x-2n 次
for(int i=2;i<=2*m;i++){
for(int j=0;j<n;j++){
x[i][j]=x[i-1][j]*x[1][j];
}
}
//求 Σxy
for(int i=1;i<=m;i++){
for(int j=0;j<n;j++)
y[i][j]=y[0][j]*x[i][j];;
}
for(int i=0;i<=2*m;i++){
double sum=0;
for(int j=0;j<n;j++)
sum+=x[i][j];
sum_x[i]=sum;
}
//变成正规矩阵
for(int i=0;i<=m;i++){
double sum=0;
for(int j=0;j<n;j++)
sum+=y[i][j];
b[i]=sum;//b【i】 得到
}
for(int i=0;i<=m;i++){
for(int j=0;j<=m;j++){
A[i][j]=sum_x[i+j];
}
A[i][m+1]=b[i];
}
Print_1();//输出看单个元素,就像列的那个表
}
//高斯消元 列主元素消元法以及求a
void Xiao_gauss(int cur)//不交换列
{
if(cur==m)//m次
{
cout<<endl;
for(int i=0;i<=m;i++)
{
for(int j=0;j<=m+1;j++)
printf("%lf ",A[i][j]);
cout<<endl;
}
return;
}
else{
int id=cur;
double max_r=0;
for(int i=cur;i<=m;i++)//找到最大值
if(fabs(A[i][cur])>max_r) max_r=fabs(A[i][cur]),id=i;
//cout<<id<<" "<<max_r<<endl;
for(int i=0;i<=m+1;i++)//两行元素调换
{
double tmp=A[id][i];
A[id][i]=A[cur][i];
A[cur][i]=tmp;
}
for(int i=cur+1;i<=m;i++)//除了本行下面的都要减
{
double t=A[i][cur]/A[cur][cur];
for(int j=cur;j<=m+1;j++)//
{
A[i][j]=A[i][j]-A[cur][j]*t;
//cout<<a[cur][j]<<endl;
}
}
Xiao_gauss(cur+1);
}
}
void f_a()
{
memset(a,0,sizeof(a));
for(int i=m;i>=0;i--)
{
double sum=0;
for(int j=i+1;j<=m;j++)
sum+=A[i][j]*a[j];
//cout<<sum<<endl;
a[i]=(A[i][m+1]-sum)/A[i][i];
}
for(int i=0;i<=m;i++)
cout<<"a"<<i<<"= "<<a[i]<<endl;
}
int main()
{
cout<<"Input the number of point"<<endl;
cin>>n;
cout<<"Input the number n: x f(x)"<<endl;
for(int i=0;i<n;i++){
x[0][i]=1;//初始化
cin>>x[1][i]>>y[0][i];
}
cout<<"Input Fitting m times"<<endl;
cin>>m;
init();
//采用高斯完全消元法
Xiao_gauss(0);
f_a();
return 0;
}
/*
7
0 1
0.5 1.75
0.6 1.96
0.7 2.19
0.8 2.44
0.9 2.71
1.0 3.00
*/