c - C中快速高效的最小二乘拟合算法?

标签 c algorithm least-squares

我正在尝试对 2 个数据数组实现线性最小二乘法拟合:时间与振幅。到目前为止我知道的唯一技术是测试 (y = m*x+b) 中所有可能的 m 和 b 点,然后找出最适合我的数据的组合,使其误差最小。但是,我认为迭代这么多组合有时是无用的,因为它测试了所有内容。有什么技术可以加快我不知道的过程吗?谢谢。

最佳答案

试试这段代码。它使 y = mx + b 适合您的 (x,y) 数据。

linreg 的参数是

linreg(int n, REAL x[], REAL y[], REAL* b, REAL* m, REAL* r)

n = number of data points
x,y  = arrays of data
*b = output intercept
*m  = output slope
*r = output correlation coefficient (can be NULL if you don't want it)

成功返回值为0,失败返回值为!=0。

这是代码

#include "linreg.h"
#include <stdlib.h>
#include <math.h>                           /* math functions */

//#define REAL float
#define REAL double


inline static REAL sqr(REAL x) {
    return x*x;
}


int linreg(int n, const REAL x[], const REAL y[], REAL* m, REAL* b, REAL* r){
    REAL   sumx = 0.0;                      /* sum of x     */
    REAL   sumx2 = 0.0;                     /* sum of x**2  */
    REAL   sumxy = 0.0;                     /* sum of x * y */
    REAL   sumy = 0.0;                      /* sum of y     */
    REAL   sumy2 = 0.0;                     /* sum of y**2  */

    for (int i=0;i<n;i++){ 
        sumx  += x[i];       
        sumx2 += sqr(x[i]);  
        sumxy += x[i] * y[i];
        sumy  += y[i];      
        sumy2 += sqr(y[i]); 
    } 

    REAL denom = (n * sumx2 - sqr(sumx));
    if (denom == 0) {
        // singular matrix. can't solve the problem.
        *m = 0;
        *b = 0;
        if (r) *r = 0;
            return 1;
    }

    *m = (n * sumxy  -  sumx * sumy) / denom;
    *b = (sumy * sumx2  -  sumx * sumxy) / denom;
    if (r!=NULL) {
        *r = (sumxy - sumx * sumy / n) /    /* compute correlation coeff */
              sqrt((sumx2 - sqr(sumx)/n) *
              (sumy2 - sqr(sumy)/n));
    }

    return 0; 
}

例子

您可以运行 this example online .

int main()
{
    int n = 6;
    REAL x[6]= {1, 2, 4,  5,  10, 20};
    REAL y[6]= {4, 6, 12, 15, 34, 68};

    REAL m,b,r;
    linreg(n,x,y,&m,&b,&r);
    printf("m=%g b=%g r=%g\n",m,b,r);
    return 0;
}

这是输出

m=3.43651 b=-0.888889 r=0.999192    

这是 Excel 图和线性拟合(用于验证)。

所有值都与上面的 C 代码完全一致(注意 C 代码返回 r 而 Excel 返回 R**2)。

Excel version of fit

关于c - C中快速高效的最小二乘拟合算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5083465/

相关文章:

统计用户输入的整数与C程序中文本文件的匹配情况

algorithm - 作业 : Dynamic programming - Find optimal subset allocation for an array of integer

matlab - Matlab中使用最小二乘法进行参数估计

python - Cython/numpy 与纯 numpy 的最小二乘拟合

c - 使用 memcpy 复制内存块时出现问题

c++ - C 系统调用 pipe、fork 和 execl

algorithm - 如果 X ≤ p Y Y ≤ p X 可以吗?

python - 如何找到 2 个序列之间的重叠,并将其返回

r - 在 R 中的最小二乘回归图中绘制垂直偏移量

c++ - Coan 给出了带有定义符号的 "expands to nothing within expression"