Least_Square.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include <stdio.h>
  2. #include "Least_Square.h"
  3. //y = Kax + Cb
  4. void least_square_init(least_square_t *ls, int samples){
  5. ls->max_samples = samples > MAX_SAMPLES?MAX_SAMPLES:samples;
  6. ls->num_samples = 0;
  7. ls->coeff.Ka = 1.0f;
  8. ls->coeff.Cb = 0.0f;
  9. ls->mul_xx = 0;
  10. ls->mul_xy = 0;
  11. ls->sum_x = 0;
  12. ls->sum_y = 0;
  13. ls->finished = 0;
  14. }
  15. int least_square_put(least_square_t *ls, double x, double y){
  16. if (!ls->finished){
  17. ls->x[ls->num_samples] = x;
  18. ls->y[ls->num_samples] = y;
  19. ls->num_samples = (ls->num_samples + 1) % ls->max_samples;
  20. ls->mul_xx += x * x;
  21. ls->mul_xy += x * y;
  22. ls->sum_x += x;
  23. ls->sum_y += y;
  24. if (ls->num_samples == 0){
  25. 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);
  26. ls->coeff.Cb = ls->sum_y / ls->max_samples - ls->coeff.Ka * ls->sum_x / ls->max_samples;
  27. ls->finished = 1;
  28. }
  29. }else {
  30. double pre_x, pre_y;
  31. pre_x = ls->x[ls->num_samples];
  32. pre_y = ls->y[ls->num_samples];
  33. ls->x[ls->num_samples] = x;
  34. ls->y[ls->num_samples] = y;
  35. ls->num_samples = (ls->num_samples + 1) % ls->max_samples;
  36. ls->mul_xx += x * x;
  37. ls->mul_xy += x * y;
  38. ls->sum_x += x;
  39. ls->sum_y += y;
  40. ls->mul_xx -= pre_x * pre_x;
  41. ls->mul_xy -= pre_x * pre_y;
  42. ls->sum_x -= pre_x;
  43. ls->sum_y -= pre_y;
  44. 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);
  45. ls->coeff.Cb = ls->sum_y / ls->max_samples - ls->coeff.Ka * ls->sum_x / ls->max_samples;
  46. ls->finished = 1;
  47. }
  48. return ls->finished;
  49. }
  50. double get_y_by_x(least_square_t *ls, double x){
  51. return ls->coeff.Ka * x + ls->coeff.Cb;
  52. }
  53. int get_x_by_y(least_square_t *ls, double y) {
  54. if (ls->coeff.Ka == 0){
  55. return -1;
  56. }
  57. int x = (y - ls->coeff.Cb)/ls->coeff.Ka;
  58. return (x >= 0) ? x : -1;
  59. }
  60. #if 0
  61. void Least_square_method(void)
  62. {
  63. int i=0;
  64. double A = 0, B = 0, C = 0, D = 0;
  65. for(i=0;i<sample_count;i++) {
  66. A += samples[i].x * samples[i].y;
  67. B += samples[i].x;
  68. C += samples[i].y;
  69. D += samples[i].x * samples[i].x;
  70. }
  71. AA = (sample_count * A - B * C) / ( sample_count * D - B * B);
  72. BB = C / sample_count - AA * B / sample_count;
  73. sys_debug("Gain = %f, zero Off = %f\n", AA, BB);
  74. }
  75. void add_smaple(float x, float y){
  76. if (sample_count < 5){
  77. samples[sample_count].x = x;
  78. samples[sample_count].y = y;
  79. sample_count ++;
  80. sys_debug("add x = %f, y = %f\n", x, y);
  81. }
  82. if (sample_count == 5){
  83. Least_square_method();
  84. }
  85. }
  86. #endif