最小二乘法求拟合曲线函数的C语言实际应用

        采用单片机等微处理器采集一些“线性”传感器数据时,注意这里的线性是指相似于线性变化,比如NTC热敏电阻、PT100铂电阻、PH复合电极传感器,这些传感器的变化特性类似于二维坐标轴上的一条斜线。如下图可以看出数据点基本在一条斜线的附近,那么我们的目的是通过单片机运行程序来求出这条斜线所对应的函数表达式。

       图中Y1、Y2、Y3、Y4、Y5 可看作为热敏电阻数值所代表的温度值大小,那么f(x) 代表斜虚线所表示的函数关系式。为了求出这个具体的函数关系式,这里我们引入最小二乘法,其基本的理论是 所有点与曲线的偏差之和最小,由于偏差存在负值,所以采用差值的平方和最小时作为曲线拟合的条件。关于最小二乘法的原理可参考:最小二乘法的本质是什么? - 知乎

       我们对曲线进行观察,或是通过将实验测得的数据画二维坐标图表观测(例如 热敏电阻阻值为【10k,11k,13k,15k】   分别对应的温度为 【25度、26度、27度、30度】,单纯举例,并非真值),即可明显看出曲线符合比例函数关系,所以我们可以设置曲线的关系式为 f(x)=ax+b;要知道最小二乘法适用的函数类型具有多种,这里是根据我们实际使用情况的一种举例。

   设上图的i,x,y 分别为:

 

 

 通过上面式子,虽然我们通过人工计算可以得出a和b的值,进而可得出函数关系式。但是对于交给单片机来计算的话,仍然不够直观,那么通过将以上算式化简即可得出如下求解a值和b值的算式,看起来已经相当直观明了,并且可以着手编程实现。(关于推导简化的原理过程可参考:好看视频-轻松有收获

0eba9d11b73bd8f9634f6ed6be1261d9.png


#include <stdio.h>
#include <math.h>

float a=0.0,b=0.0;   //所求系数
float y[3]={4,7,10}; //因变量数组

float x[3]={3.071,2.535,2.0666}; //自变量数组

//最小二乘法 获取a,b
//x[]: 自变量数组  y[]: 因变量数组  num: 数组元素个数,两组必须一致  a:系数 b:系数
void leastSquareLinearFit(float x[], float y[], const int num, float &a, float &b)
{
    float mxy=0.0,xx=0.0,yy=0.0,x2=0.0,x22=0.0;
    int i;    
    
    for(i=0;i<num;i++)
    {
    mxy=num*x[i]*y[i]+mxy;
    
    xx=1.0*x[i]+xx;
    
    yy=1.0*y[i]+yy;
    
    x2=1.0*x[i]*x[i]*num+x2;
    
    x22=1.0*x[i]+x22;
    
    }

    b=1.0*(mxy-xx*yy)/(x2-x22*x22);
    
    a=1.0*yy/num-b*xx/num;
    
    printf("Y=%0.3fx+%0.3f\n",b,a);    
    
    
}
int main()

{
    
 leastSquareLinearFit(x,y,3,a,b);
 
 return 0;

}

 

     以上为利用最小二乘法求出函数a,b值的完整C语言代码,以上数组x,y分别表示PH传感器电极电压和所对应PH值的关系。这里我们可以通过在线C编译器来打印出运算结果a,b值。

在线C编译器地址:http://www.dooccn.com/c/

编译结果如下图:

                                                        

       至此,采用最小二乘法求曲线拟合方程式的验证完毕,另外在有些时候,我们并不需要单片机等处理器来计算曲线方程式时,我们可以利用将得到的数组填入excel表格,利用excel的曲线拟合功能,同样可以得出曲线拟合函数方程式,如下图。(excel曲线拟合可参考:怎么用excel拟合曲线-百度经验

       可看到采用excel曲线拟合功能得到的函数a值和b值和采用C语言最小二乘法的计算结果是一致的,EXCEL中的R平方值是趋势线拟合程度的指标,它的数值大小可以反映趋势线的估计值与对应的实际数据之间的拟合程度,拟合程度越高,趋势线的可靠性就越高。

R平方值是取值范围在0~1之间的数值,当趋势线的 R 平方值等于 1 或接近 1 时,其可靠性最高,反之则可靠性较低。R平方值也称为决定系数。

  • 10
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

>行者<

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值