Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

116 righe
3.3 KiB

  1. /*
  2. * aptdec - A lightweight FOSS (NOAA) APT decoder
  3. * Copyright (C) 2019-2023 Xerbo (xerbo@protonmail.com)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. #include "algebra.h"
  19. #include <stdlib.h>
  20. #include <math.h>
  21. // Find the best linear equation to estimate the value of the
  22. // dependent variable from the independent variable
  23. linear_t linear_regression(const float *independent, const float *dependent, size_t len) {
  24. // Calculate mean of the dependent and independent variables (this is the centoid)
  25. float dependent_mean = 0.0f;
  26. float independent_mean = 0.0f;
  27. for (size_t i = 0; i < len; i++) {
  28. dependent_mean += dependent[i] / (float)len;
  29. independent_mean += independent[i] / (float)len;
  30. }
  31. // Calculate slope
  32. float a = 0.0f;
  33. {
  34. float a_numerator = 0.0f;
  35. float a_denominator = 0.0f;
  36. for (size_t i = 0; i < len; i++) {
  37. a_numerator += (independent[i] - independent_mean) * (dependent[i] - dependent_mean);
  38. a_denominator += powf(independent[i] - independent_mean, 2.0f);
  39. }
  40. a = a_numerator / a_denominator;
  41. }
  42. // We can now solve for the y-intercept since we know the slope
  43. // and the centoid, which the line must pass through
  44. float b = dependent_mean - a * independent_mean;
  45. // printf("y(x) = %fx + %f\n", a, b);
  46. return (linear_t){a, b};
  47. }
  48. // "Sample" standard deviation
  49. float standard_deviation(const float *data, size_t len) {
  50. float mean = meanf(data, len);
  51. float deviation_mean = 0.0f;
  52. for (size_t i = 0; i < len; i++) {
  53. float deviation = data[i] - mean;
  54. deviation_mean += deviation * deviation;
  55. }
  56. return sqrtf(deviation_mean / (float)(len-1));
  57. }
  58. float sumf(const float *x, size_t len) {
  59. float sum = 0.0f;
  60. for (size_t i = 0; i < len; i++) {
  61. sum += x[i];
  62. }
  63. return sum;
  64. }
  65. float meanf(const float *x, size_t len) {
  66. return sumf(x, len) / (float)len;
  67. }
  68. void normalizef(float *x, size_t len) {
  69. float sum = sumf(x, len);
  70. for (size_t i = 0; i < len; i++) {
  71. x[i] /= sum;
  72. }
  73. }
  74. static int sort_func(const void *a, const void *b) {
  75. return *(float *)b > *(float *)a ? 1 : -1;
  76. }
  77. float medianf(float *data, size_t len) {
  78. qsort(data, len, sizeof(float), sort_func);
  79. if (len % 2 == 0) {
  80. return (data[len/2] + data[len/2 - 1]) / 2.0f;
  81. } else {
  82. return data[len/2];
  83. }
  84. }
  85. float linear_calc(float x, linear_t line) {
  86. return x * line.a + line.b;
  87. }
  88. float quadratic_calc(float x, quadratic_t quadratic) {
  89. return x*x * quadratic.a + x * quadratic.b + quadratic.c;
  90. }
  91. float sincf(float x) {
  92. if (x == 0.0f) {
  93. return 1.0f;
  94. }
  95. return sinf(M_PIf * x) / (M_PIf * x);
  96. }