stats.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <math.h>
  2. static int float_cmp(const void* a, const void* b) {
  3. float* c = *(float*)a;
  4. float* d = *(float*)b;
  5. return c == d ? 0 : (c > d ? 1 : 0);
  6. }
  7. typedef struct {
  8. size_t index;
  9. float val;
  10. } bucket_f;
  11. int calc_stats_f(void* data, size_t stride, ptrdiff_t val_offset, size_t len, sti_stats* st) {
  12. if(len < 2) return 1;
  13. double dlen = len;
  14. double sum = 0;
  15. bucket_f* tmp = malloc(sizeof(*tmp) * len);
  16. for(size_t i = 0; i < len; i++) {
  17. tmp[i].index = i;
  18. tmp[i].val = *((float*)((char*)data + (stride * i) + val_offset));
  19. sum += tmp[i].val;
  20. }
  21. qsort(tmp, len, sizeof(*tmp), float_cmp);
  22. st->sum = sum;
  23. st->min = tmp[0].val;
  24. st->min_index = tmp[0].index;
  25. st->max = tmp[len-1].val;
  26. st->max_index = tmp[len-1].index;
  27. st->mean = sum / dlen;
  28. size_t mi = floor((dlen / 2.0) + 0.5);
  29. st->median_index = tmp[mi].index;
  30. st->median = tmp[mi].val;
  31. sum = 0;
  32. float mean = st->mean;
  33. for(size_t i = 0; i < len; i++) {
  34. float v = tmp[i].val - mean;
  35. v *= v;
  36. sum += v;
  37. }
  38. sum /= dlen;
  39. st->pop_var = sum;
  40. st->std_dev = sqrt(sum);
  41. free(tmp);
  42. return 0;
  43. };
  44. static int double_cmp(const void* a, const void* b) {
  45. double* c = *(double*)a;
  46. double* d = *(double*)b;
  47. return c == d ? 0 : (c > d ? 1 : 0);
  48. }
  49. typedef struct {
  50. size_t index;
  51. double val;
  52. } bucket_d;
  53. int calc_stats_d(void* data, size_t stride, ptrdiff_t val_offset, size_t len, sti_stats* st) {
  54. if(len < 2) return 1;
  55. double dlen = len;
  56. double sum = 0;
  57. bucket_d* tmp = malloc(sizeof(*tmp) * len);
  58. for(size_t i = 0; i < len; i++) {
  59. tmp[i].index = i;
  60. tmp[i].val = *((double*)((char*)data + (stride * i) + val_offset));
  61. sum += tmp[i].val;
  62. }
  63. qsort(tmp, len, sizeof(*tmp), double_cmp);
  64. st->sum = sum;
  65. st->min = tmp[0].val;
  66. st->min_index = tmp[0].index;
  67. st->max = tmp[len-1].val;
  68. st->max_index = tmp[len-1].index;
  69. st->mean = sum / dlen;
  70. size_t mi = floor((dlen / 2.0) + 0.5);
  71. st->median_index = tmp[mi].index;
  72. st->median = tmp[mi].val;
  73. sum = 0;
  74. double mean = st->mean;
  75. for(size_t i = 0; i < len; i++) {
  76. double v = tmp[i].val - mean;
  77. v *= v;
  78. sum += v;
  79. }
  80. sum /= dlen;
  81. st->pop_var = sum;
  82. st->std_dev = sqrt(sum);
  83. free(tmp);
  84. return 0;
  85. };