最小二乘法采用C语言.doc
《最小二乘法采用C语言.doc》由会员分享,可在线阅读,更多相关《最小二乘法采用C语言.doc(6页珍藏版)》请在冰点文库上搜索。
![最小二乘法采用C语言.doc](https://file1.bingdoc.com/fileroot1/2023-5/3/4e48610f-b133-4191-962a-47badf30fd22/4e48610f-b133-4191-962a-47badf30fd221.gif)
最小二乘法C语言
1.实验目的:
进一步熟悉曲线拟合的最小二乘法。
掌握编程语言字符处理程序的设计和调试技术。
2.实验要求:
输入:
已知点的数目以及各点坐标。
输出:
根据最小二乘法原理以及各点坐标求出拟合曲线。
3.程序流程:
(1)输入已知点的个数;
(2)分别输入已知点的X坐标;
(3)分别输入已知点的Y坐标;
(4)通过调用函数,求出拟合曲线。
最小二乘法原理如下:
根据一组给定的实验数据,求出自变量x与因变量y的函数关系,只要求在给定点上的误差的平方和最小.当时,即
(4.4.1)
这里是线性无关的函数族,假定在上给出一组数据,以及对应的一组权,这里为权系数,要求使最小,其中 (4.4.2)
(4.4.2)中实际上是关于的多元函数,求I的最小值就是求多元函数I的极值,由极值必要条件,可得
(4.4.3)
根据内积定义引入相应带权内积记号
(4.4.4)
则(4.4.3)可改写为
这是关于参数的线性方程组,用矩阵表示为
(4.4.5)
(4.4.5)称为法方程.当线性无关,且在点集上至多只有n个不同零点,则称在X上满足Haar条件,此时(4.4.5)的解存在唯一。
记(4.4.5)的解为
从而得到最小二乘拟合曲线
(4.4.6)
可以证明对,有
故(4.4.6)得到的即为所求的最小二乘解.它的平方误差为
(4.4.7)
均方误差为
在最小二乘逼近中,若取,则,表示为
(4.4.8)
此时关于系数的法方程(4.4.5)是病态方程,通常当n≥3时都不直接取作为基。
程序流程图:
开始
↓
输入已知点个数n
输入已知点的X坐标
↓
输入已知点的Y坐标
↓
输出结果
↓
程序:
#include
#include
#include
#include
floataverage(intn,float*x)
{inti;
floatav;
av=0;
for(i=0;iav+=*(x+i);
av=av/n;
return(av);
}
//平方和
floatspfh(intn,float*x)
{inti;
floata,b;
a=0;
for(i=0;ia+=(*(x+i))*(*(x+i));
return(a);
}
//和平方
floatshpf(intn,float*x)
{inti;
floata,b;
a=0;
for(i=0;ia=a+*(x+i);
b=a*a/n;
return(b);
}
//两数先相乘,再相加
floatdcj(intn,float*x,float*y)
{inti;
floata;
a=0;
for(i=0;ia+=(*(x+i))*(*(y+i));
return(a);
}
//两数先相加,再相乘
floatdjc(intn,float*x,float*y)
{inti;
floata=0,b=0;
for(i=0;i{a=a+*(x+i);
b=b+*(y+i);
}
a=a*b/n;
return(a);
}
//系数a
floatxsa(intn,float*x,float*y)
{floata,b,c,d,e;
a=spfh(n,x);
b=shpf(n,x);
c=dcj(n,x,y);
d=djc(n,x,y);
e=(c-d)/(a-b);
//printf("%f%f%f%f",a,b,c,d);
return(e);
}
floathe(intn,float*y)
{inti;
floata;
a=0;
for(i=0;ia=a+*(y+i);
return(a);
}
floatxsb(intn,float*x,float*y,floata)
{floatb,c,d;
b=he(n,y);
c=he(n,x);
d=(b-a*c)/n;
return(d);
}
voidmain()
{intn,i;
float*x,*y,a,b;
printf("请输入将要输入的有效数值组数n的值:
");
scanf("%d",&n);
x=(float*)calloc(n,sizeof(float));
if(x==NULL)
{printf("内存分配失败");
exit
(1);
}
y=(float*)calloc(n,sizeof(float));
if(y==NULL)
{printf("内存分配失败");
exit
(1);
}
printf("请输入x的值\n");
for(i=0;iprintf("请输入y的值,请注意与x的值一一对应:
\n");
for(i=0;ifor(i=0;i{printf("x[%d]=%3.2f",i,*(x+i));
printf("y[%d]=%3.2f\n",i,*(y+i));
}
a=xsa(n,x,y);
b=xsb(n,x,y,a);
printf("经最小二乘法拟合得到的一元线性方程为:
\n");
printf("f(x)=%3.2fx+%3.2f\n",a,b);
}