数值作业:最小二乘法进行线性拟合之C语言代码

  • Post author:
  • Post category:其他


作图法求出直线的斜率a和截据b,可以确定这条直线所对应的经验公式,但用作图法拟合直线时,由于作图连线有较大的随意性,尤其在测量数据比较分散时,对同一组测量数据,不同的人去处理,所得结果有差异,因此是一种粗略的数据处理方法,求出的a和b误差较大。用最小二乘法拟合直线处理数据时,任何人去处理同一组数据,只要处理过程没有错误,得到的斜率a和截据b是唯一的。

最小二乘法就是将一组符合Y=a+bX关系的测量数据,用计算的方法求出最佳的a和b。显然,关键是如何求出最佳的a和b。

(1) 求回归直线

设直线方程的表达式为:

y=a+bx;

(2)然后后面一大部分bb的书上都有,我们要做的就是把数学公式转化成代码,仅此而已,说实话,我压根看不懂书上说杀玩意,毕竟数值老师也有点跟煞笔一样,记得刚开始几章一直讲天文地理的知识,什么九章算术里面的题目拿出来说,还让我们有兴趣去买,我有句妈卖批是一定要讲的,那么晦涩难懂的东西,你让我们看?跟个勺一样,后来就基本不去上课了..不过书上看不懂没关系,只需要转化成代码是能容易实现的:下面上自己的代码;

/********************************************
    > File Name: spantwo.c
    > Author:chendiyang
    > School:WUST_CST_1501班
    > Myblog:www.chendsir.com
    > Mail:1441353519@qq.com 
    > Created Time: 2017年04月22日 星期六 22时29分41秒
 ************************************************************************/
#include <stdio.h>
#define MAX 30          //最多输入30个点进行线性拟和

typedef struct POINT//点的结构
{
    double x;
    double y;
}Point;

int main()
{
    int m;//输入点的个数
    int i;
    Point points[MAX];//用来存储点
    static double u11,u12,u21,u22,c1,c2;//用来构建法方程组的变量
    double a,b,tmp;
    printf("\n请输入点数:");
    scanf("%d",&m);
    if(m>MAX)
    {
        return 1;
    }
    if(m<=0)
    {
        return 1;
    }
    printf("\n请输入x点y点的坐标:\n");
    for(i=0;i<m;i++)
    {
        scanf("%lf%lf",&points[i].x,&points[i].y);
    }
    //列出方程U(a,b)
    for(i=0;i<m;i++)//即解法方程组
    {
        u21+=points[i].x;
        u22+=points[i].x*points[i].x;
        c1+=points[i].y;
        c2+=points[i].x*points[i].y;
    }
    u12=u21;
    u11=m;
    //进行求解
    a=(c1*u22-c2*u12)/(u11*u22-u12*u21);
    b=(c1*u21-c2*u11)/(u21*u12-u22*u11);

    //输出最小二乘解
    printf("\n最小二乘解的线性方程为 :S(x)=%f+%fx\n",a,b);

    return 0;
}
 运行结果如图:


这里写图片描述

输入21个点进行线性拟合,输出最小二乘解.上面是在网上找的例题,结果是对的,不过为了试试书上的题目也是不是正确的,于是,在数值书的106面的例1,输入7个点,求出最小二乘解,结果如图:

这里写图片描述

结果显示:S(x)=0.842857+4.571429x ,107面书上的答案是:P(x)=0.843+4.57x,很明显,答案是正确的,而且我这个的精确度更高.此题目完毕!讲道理,这几天都在忙这个,压根不知道有什么意义。。



版权声明:本文为Chen_dSir原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。