Przeglądaj źródła

解决最小二乘bug

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 lat temu
rodzic
commit
85d2a8b769

+ 27 - 15
Application/app/sox/Least_Square.c

@@ -3,7 +3,7 @@
 
 //y = Kax + Cb
 void least_square_init(least_square_t *ls, int samples){
-	ls->max_samples = samples;
+	ls->max_samples = samples > MAX_SAMPLES?MAX_SAMPLES:samples;
 	ls->num_samples = 0;
 	ls->coeff.Ka = 1.0f;
 	ls->coeff.Cb = 0.0f;
@@ -14,32 +14,44 @@ void least_square_init(least_square_t *ls, int samples){
 	ls->finished = 0;
 }
 int least_square_put(least_square_t *ls, double x, double y){
-	if (ls->num_samples < ls->max_samples){
-		ls->num_samples ++;
-		ls->last_x = x;
-		ls->last_y = y;
+	if (!ls->finished){
+		ls->x[ls->num_samples] = x;
+		ls->y[ls->num_samples] = y;
+		ls->num_samples = (ls->num_samples + 1) % ls->max_samples;
 		ls->mul_xx += x * x;
 		ls->mul_xy += x * y;
 		ls->sum_x += x;
 		ls->sum_y += y;
-		return 0;
+		if (ls->num_samples == 0){
+			ls->coeff.Ka = (ls->max_samples * ls->mul_xy - ls->sum_x * ls->sum_y) / (ls->max_samples * ls->mul_xx - ls->sum_x * ls->sum_x);
+			ls->coeff.Cb = ls->sum_y / ls->max_samples - ls->coeff.Ka * ls->sum_x / ls->max_samples;
+			ls->finished = 1;
+		}
 	}else {
-		ls->coeff.Ka = (ls->max_samples * ls->mul_xy - ls->sum_x * ls->sum_y) / (ls->max_samples * ls->mul_xx - ls->sum_x * ls->sum_x);
-		ls->coeff.Cb = ls->sum_y / ls->max_samples - ls->coeff.Ka * ls->sum_x / ls->max_samples;
+		double pre_x, pre_y;
+		pre_x = ls->x[ls->num_samples];
+		pre_y = ls->y[ls->num_samples];
+
+		ls->x[ls->num_samples] = x;
+		ls->y[ls->num_samples] = y;
+		ls->num_samples = (ls->num_samples + 1) % ls->max_samples;
+
 		ls->mul_xx += x * x;
 		ls->mul_xy += x * y;
 		ls->sum_x += x;
 		ls->sum_y += y;
 
-		ls->mul_xx -= ls->last_x * ls->last_x;
-		ls->mul_xy -= ls->last_x * ls->last_y;
-		ls->sum_x -= ls->last_x;
-		ls->sum_y -= ls->last_y;
-		ls->last_x = x;
-		ls->last_y = y;
+		ls->mul_xx -= pre_x * pre_x;
+		ls->mul_xy -= pre_x * pre_y;
+		ls->sum_x -= pre_x;
+		ls->sum_y -= pre_y;
+		
+		ls->coeff.Ka = (ls->max_samples * ls->mul_xy - ls->sum_x * ls->sum_y) / (ls->max_samples * ls->mul_xx - ls->sum_x * ls->sum_x);
+		ls->coeff.Cb = ls->sum_y / ls->max_samples - ls->coeff.Ka * ls->sum_x / ls->max_samples;
+
 		ls->finished = 1;
-		return 1;
 	}
+	return ls->finished;
 }
 
 double get_y_by_x(least_square_t *ls, double x){

+ 3 - 3
Application/app/sox/Least_Square.h

@@ -4,12 +4,12 @@ typedef struct {
 	double Ka;
 	double Cb;
 }linear_ceoff_t;
-
+#define MAX_SAMPLES 30
 typedef struct {
 	int max_samples;
 	int num_samples;
-	double last_x;
-	double last_y;
+	double x[MAX_SAMPLES];
+	double y[MAX_SAMPLES];
 	double mul_xx;
 	double mul_xy;
 	double sum_x;