@cryptotaxi247 / netdata-1 / commits / 337b2007a

allow median() to be called with sorted array

Costa Tsaousis (ktsaou) committed Apr 26, 2017 at 10:25 UTC 337b2007a14b77106219586363fdc05115e37bee
2 files changed +36 -8
src/statistical.c
+32 -8
@@ -64,7 +64,17 @@ static int qsort_compare(const void *a, const void *b) {
64 return 0;
65 }
66
67 -long double median(long double *series, size_t entries) {
67 +inline void sort_series(long double *series, size_t entries) {
68 + qsort(series, entries, sizeof(long double), qsort_compare);
69 +}
70 +
71 +inline long double *copy_series(long double *series, size_t entries) {
72 + long double *copy = mallocz(sizeof(long double) * entries);
73 + memcpy(copy, series, sizeof(long double) * entries);
74 + return copy;
75 +}
76 +
77 +long double median_on_sorted_series(long double *series, size_t entries) {
78 if(unlikely(entries == 0))
79 return NAN;
80
@@ -74,19 +84,33 @@ long double median(long double *series, size_t entries) {
84 if(unlikely(entries == 2))
85 return (series[0] + series[1]) / 2;
86
77 - long double *copy = mallocz(sizeof(long double) * entries);
78 - memcpy(copy, series, sizeof(long double) * entries);
79 - qsort(copy, entries, sizeof(long double), qsort_compare);
80 -
87 long double avg;
88 if(entries % 2 == 0) {
89 size_t m = entries / 2;
84 - avg = (copy[m] + copy[m + 1]) / 2;
90 + avg = (series[m] + series[m + 1]) / 2;
91 }
92 else {
87 - avg = copy[entries / 2];
93 + avg = series[entries / 2];
94 }
95
96 + return avg;
97 +}
98 +
99 +long double median(long double *series, size_t entries) {
100 + if(unlikely(entries == 0))
101 + return NAN;
102 +
103 + if(unlikely(entries == 1))
104 + return series[0];
105 +
106 + if(unlikely(entries == 2))
107 + return (series[0] + series[1]) / 2;
108 +
109 + long double *copy = copy_series(series, entries);
110 + sort_series(copy, entries);
111 +
112 + long double avg = median_on_sorted_series(copy, entries);
113 +
114 freez(copy);
115 return avg;
116 }
@@ -98,7 +122,7 @@ long double moving_median(long double *series, size_t entries, size_t period) {
122 return median(series, entries);
123
124 size_t len = entries - period;
101 - long double *data = mallocz(sizeof(long double) * len);
125 + long double *data = copy_series(series, entries);
126
127 size_t i;
128 for(i = period; i < entries; i++) {
src/statistical.h
+4
@@ -11,4 +11,8 @@ extern long double single_exponential_smoothing(long double *series, size_t entr
11 extern long double double_exponential_smoothing(long double *series, size_t entries, long double alpha, long double beta, long double *forecast);
12 extern long double holtwinters(long double *series, size_t entries, long double alpha, long double beta, long double gamma, long double *forecast);
13
14 +extern long double median_on_sorted_series(long double *series, size_t entries);
15 +extern long double *copy_series(long double *series, size_t entries);
16 +extern void sort_series(long double *series, size_t entries);
17 +
18 #endif //NETDATA_STATISTICAL_H