line_fit

#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章