最小二乘法拟合多项式

最小二乘法拟合多项式
求解
给定数据点(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
*/

猜你喜欢

转载自blog.csdn.net/miranda_ymz/article/details/81071805
今日推荐