You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

119 lines
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. float standard_deviation(const float *data, size_t len) {
  49. float mean = 0.0f;
  50. for (size_t i = 0; i < len; i++) {
  51. mean += data[i];
  52. }
  53. mean /= (float)len;
  54. float deviation_mean = 0.0f;
  55. for (size_t i = 0; i < len; i++) {
  56. float deviation = data[i] - mean;
  57. deviation_mean += deviation * deviation;
  58. }
  59. return sqrtf(deviation_mean / (float)len);
  60. }
  61. float sumf(const float *x, size_t len) {
  62. float sum = 0.0f;
  63. for (size_t i = 0; i < len; i++) {
  64. sum += x[i];
  65. }
  66. return sum;
  67. }
  68. float meanf(const float *x, size_t len) {
  69. return sumf(x, len) / (float)len;
  70. }
  71. void normalizef(float *x, size_t len) {
  72. float sum = sumf(x, len);
  73. for (size_t i = 0; i < len; i++) {
  74. x[i] /= sum;
  75. }
  76. }
  77. static int sort_func(const void *a, const void *b) {
  78. return *(float *)b > *(float *)a ? 1 : -1;
  79. }
  80. float medianf(float *data, size_t len) {
  81. qsort(data, len, sizeof(float), sort_func);
  82. if (len % 2 == 0) {
  83. return (data[len/2] + data[len/2 - 1]) / 2.0f;
  84. } else {
  85. return data[len/2];
  86. }
  87. }
  88. float linear_calc(float x, linear_t line) {
  89. return x * line.a + line.b;
  90. }
  91. float quadratic_calc(float x, quadratic_t quadratic) {
  92. return x*x * quadratic.a + x * quadratic.b + quadratic.c;
  93. }
  94. float sincf(float x) {
  95. if (x == 0.0f) {
  96. return 1.0f;
  97. }
  98. return sinf(M_PIf * x) / (M_PIf * x);
  99. }