#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define POINTS_NUM 6
typedef struct {
double x;
double y;
}typePoints;
typePoints points[POINTS_NUM] =
{
{
0 , 0.002
},
{
0.1 , 0.082
},
{
0.2 , 0.162
},
{
0.5 , 0.407
},
{
1 , 0.805
},
{
1.5 , 1.185
}
};
/*
* 最小二乘法直线拟合(不是常见的一元线性回归算法)
* 将离散点拟合为 a x + b y + c = 0 型直线
* 假设每个点的 X Y 坐标的误差都是符合 0 均值的正态分布的。
* 与一元线性回归算法的区别:一元线性回归算法假定 X 是无误差的,只有 Y 有误差。
*/
void lineFit(double *a , double *b , double *c)
{
int i;
double x_mean = 0;
double y_mean = 0;
for(i = 0; i < POINTS_NUM; i++)
{
x_mean += points[i].x;
y_mean += points[i].y;
}
x_mean /= POINTS_NUM;
y_mean /= POINTS_NUM; //至此,计算出了 x y 的均值
double Dxx = 0, Dxy = 0, Dyy = 0;
for(i = 0; i < POINTS_NUM; i++)
{
Dxx += (points[i].x - x_mean) * (points[i].x - x_mean);
Dxy += (points[i].x - x_mean) * (points[i].y - y_mean);
Dyy += (points[i].y - y_mean) * (points[i].y - y_mean);
}
double lambda = ( (Dxx + Dyy) - sqrt( (Dxx - Dyy) * (Dxx - Dyy) + 4 * Dxy * Dxy) ) / 2.0;
double den = sqrt( Dxy * Dxy + (lambda - Dxx) * (lambda - Dxx) );
*a = Dxy / den;
*b = (lambda - Dxx) / den;
*c = - (*a) * x_mean - (*b) * y_mean;
}
int main(int argc, char *argv[]) {
double a , b , c;
lineFit(&a,&b,&c);
printf("slope = %f;intercept = %f",(-a/b),(-c/b));
system("pause");
return 0;
}
line_fit
最新推荐文章于 2024-04-15 09:58:32 发布