最小二乘法-直线拟合-C代码实现

最小二乘法(又称最小平方法)是一种数学优化技术。

它通过最小化误差的平方和寻找数据的最佳函数匹配。

利用最小二乘法可以简便地求得未知的数据,

并使得这些求得的数据与实际数据之间误差的平方和为最小。

假设已知有N个点,设这条直线方程为:  y = a·x + b

其中,a和b的计算公式如下:

本文对于推导过程不在赘述,网上都有。

算法代码和效果演示


算法代码如下:

//-------------------------------------------------------------
//功能 : 最小二乘法直线拟合 y = a·x + b, 计算系数a 和 b
//参数 : x -- 辐照度的数组
//       y --  功率的数组
//       num 是数组包含的元素个数,x[]和y[]的元素个数必须相等
//       a,b 都是返回值
//返回 : 拟合计算成功返回true, 拟合计算失败返回false
//作者 :Long
//-------------------------------------------------------------
bool leastSquareLinearFit(float x[], float y[], const int num, float &a, float &b)
{
    float sum_x2 = 0.0;
    float sum_y  = 0.0;
    float sum_x  = 0.0;
    float sum_xy = 0.0;


    try {
        for (int i = 0; i < num; ++i) {
            sum_x2 += x[i]*x[i];
            sum_y  += y[i];
            sum_x  += x[i];
            sum_xy += x[i]*y[i];
        }
    } catch (...) {
        return false;
    }


    a = (num*sum_xy - sum_x*sum_y)/(num*sum_x2 - sum_x*sum_x);
    b = (sum_x2*sum_y - sum_x*sum_xy)/(num*sum_x2-sum_x*sum_x);


    return true;
}


数据样本:
x:

float temp[96] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.46667, 11.4667, 31.6, 52.7333, 80.3333, 116.333, 156.6, 199.4, 242.2, 283.4, 329.2, 379.333, 431.333, 482.6, 541, 594.4, 643.533, 692.133, 736.267, 772.667, 810.133, 841.867, 868.2, 892.4, 917.667, 939.8, 954.667, 969, 976.8, 983.4, 987.467, 994.933, 1023.67, 875.2, 873.933, 758.8, 678.2, 515.867, 782.533, 908.8, 779.2, 831.4, 645.533, 734.067, 679.533, 610.267, 565.067, 512.467, 462, 405.2, 354.133, 302, 247.8, 191.533, 140, 94.2667, 57.5333, 25.9333, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // x

y:

float tempy[96] = {0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 0.595, 1.785, 2.57833, 3.927, 5.79233, 7.379, 9.48133, 11.1473, 12.4167, 13.6627, 16.193701, 18.248699, 19.042, 19.042, 19.105301, 16.6383, 17.240999, 14.631, 11.8217, 11.663, 12.155, 15.488, 21.859301, 19.32, 19.042, 19.6133, 21.105, 22.9937, 20.827299, 23.858299, 23.0333, 19.2883, 15.6937, 21.5893, 23.802999, 20.518299, 21.5893, 17.907301, 17.971001, 17.574301, 16.781, 15.5513, 12.3773, 10.2747, 8.60867, 6.86333, 5.39567, 3.88767, 2.856, 2.142, 2.142, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952, 0.952 }; // y    


计算结果:

a = 0.0215136

b = 0.608488
————————————————
版权声明:本文为CSDN博主「杏儿黄」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36373500/article/details/87181069

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值