/**************运用高斯消去及最小二乘法求最小二乘拟合的经验直线*******/
/***************本例使用6个拟合点,若调节可调节宏定义中N*********/
#include <stdio.h>
#include<malloc.h>
#define N 7
#define n 2
double *gassy(double sum,double sum_x,double sum_y,double sum_x2,double sum_xy )//运用高斯消去法
{
int k,i,j,q,p;
double b[n][n+1]={sum,sum_x,sum_y,sum_x,sum_x2,sum_xy},m;
double *a;
a=(double *)malloc(sizeof(int)*n);
//printf("消元过程\n");
for(k=0;k<=n-2;k++)
{
if(b[k][k]==0)
break;
for(i=k+1;i<=n-1;i++)
{
m=b[i][k]/b[k][k];
b[i][k]=0;
for(j=k+1;j<=n;j++)
{
b[i][j]=b[i][j]-m*b[k][j];
}
}
}
for(q=0;q<n;q++)
{
for(p=0;p<=n;p++)
printf("%.4lf\t",b[q][p]);
printf("\n");
}
//printf("回代过程\n");
a[n-1]=b[n-1][n]/b[n-1][n-1];
for(i=n-2;i>=0;i--)
{
int m;
double s[n-1]={0};
for(m=n-1;m>i;m--)
{
s[i]=s[i]+a[m]*b[i][m];
}
a[i]=(b[i][n]-s[i])/b[i][i];
}
return a;
}
void main()
{
int i;
double x[N]={0.6,1.3,1.64,1.8,2.1,2.3,2.44},y[N]={7.05,12.2,14.4,15.2,17.4,19.6,20.2},*p;
double sum=0,sum_x=0,sum_x2=0,sum_y=0,sum_xy=0;
for( i=0;i<N;i++)
{
printf("请输入x,y");
scanf_s("%lf%lf",x[i],y[i]);
}
for( i=0;i<N;i++)
{
sum++;
sum_x=sum_x+x[i];
sum_x2=sum_x2+x[i]*x[i];
sum_y=sum_y+y[i];
sum_xy=sum_xy+x[i]*y[i];
}
p=gassy(sum,sum_x,sum_y,sum_x2,sum_xy);
printf("最小二乘经验直线为y=%lf+%lfx",p[0],p[1]);
}
12-16