# 算法精解:最小二乘法C实现

y(x)是n个点(x0,y0) , ... (Xn-1 , Yn-1)的最佳拟合线。

b1 = (n * sigma(Xi * Yi) - singma(Xi)*singma(Yi) ) / (n*singma(pow(Xi)) - pow((singma(Xi))) ;

b0 = (sigma(Yi) - b1 * singma(Xi)) / n ;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define NR(x) sizeof(x)/sizeof(x[0])
//最小二乘法实现
void lsqe(const double *x, const double *y, int n, double *b1, double *b0)
{
int  i;
double  sumx,sumy,sumx2,sumxy;
sumx = 0.0;
sumy = 0.0;
sumx2 = 0.0;
sumxy = 0.0;
//计算N次
for (i = 0; i < n; i++) {
//将横坐标方向的x值进行累加
sumx = sumx + x[i];
//将纵坐标方向的y值进行累加
sumy = sumy + y[i];
sumx2 = sumx2 + pow(x[i], 2.0);
sumxy = sumxy + (x[i] * y[i]);
}
//根据公式求解b1和b0的值
*b1 = (sumxy - ((sumx * sumy)/(double)n)) / (sumx2-(pow(sumx,2.0)/(double)n));
*b0 = (sumy - ((*b1) * sumx)) / (double)n;

return;
}

int main(void)
{
double x[] = {1.1 , 1.2 , 1.3 , 1.4 , 1.5 ,1.6} ;
double y[] = {4.1 , 4.2 , 4.3 , 4.4 , 4.5 , 4.6} ;
double b0 , b1 ;
lsqe(x,y,NR(x),&b0,&b1);
printf("%lf,%lf\n",b0,b1);
return 0 ;
}

1.000000 ,  3.00000

+ 订阅