SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
median.c File Reference

Detailed Description

Computes statistical measures such as median, percentiles, average, and middle values.

This file contains functions to compute median, percentiles, averages, and the middle value of datasets. See also the find_XX() routines in rowmedian.c which return the position of the median and other statistics.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, Y. Wang

Definition in file median.c.

#include "mdb.h"

Go to the source code of this file.

Functions

long compute_median (double *value, double *x, long n)
 Computes the median of an array of doubles.
 
long compute_percentile (double *value, double *x, long n, double percentile)
 Computes a specific percentile of an array of doubles.
 
long compute_percentiles (double *position, double *percent, long positions, double *x, long n)
 Computes multiple percentiles of an array of doubles.
 
long compute_percentiles_flagged (double *position, double *percent, long positions, double *x, int32_t *keep, int64_t n)
 Computes multiple percentiles of an array of doubles, considering only flagged elements.
 
long compute_average (double *value, double *data, int64_t n)
 Computes the average of an array of doubles.
 
long compute_middle (double *value, double *data, long n)
 Computes the middle value between the minimum and maximum of an array of doubles.
 
long approximate_percentiles (double *position, double *percent, long positions, double *x, long n, long bins)
 Approximates multiple percentiles of an array of doubles using histogram bins.
 

Function Documentation

◆ approximate_percentiles()

long approximate_percentiles ( double * position,
double * percent,
long positions,
double * x,
long n,
long bins )

Approximates multiple percentiles of an array of doubles using histogram bins.

Parameters
positionPointer to the array to store the computed percentile positions.
percentPointer to the array of percentiles to compute (each value between 0-100).
positionsNumber of percentiles to compute.
xPointer to the array of doubles.
nNumber of elements in the array.
binsNumber of histogram bins to use for approximation.
Returns
Returns 1 on success, 0 on failure.

Definition at line 195 of file median.c.

196 {
197 double *hist, *cdf, xMin, xMax, xCenter, xRange;
198 long i, j, k;
199 if (bins < 2 || positions <= 0 || n <= 0)
200 return 0;
201 for (i = 0; i < positions; i++)
202 if (percent[i] < 0 || percent[i] > 100)
203 return 0;
204 if (!(hist = malloc(sizeof(*hist) * bins)))
205 return 0;
206 find_min_max(&xMin, &xMax, x, n);
207 xCenter = (xMax + xMin) / 2;
208 xRange = (xMax - xMin) * (1 + 1. / bins) / 2;
209 xMin = xCenter - xRange;
210 xMax = xCenter + xRange;
211 make_histogram(hist, bins, xMin, xMax, x, n, 1);
212
213 cdf = hist;
214 for (i = 1; i < bins; i++)
215 cdf[i] += cdf[i - 1];
216 for (i = 0; i < bins; i++)
217 cdf[i] /= cdf[bins - 1];
218
219 for (j = 0; j < positions; j++) {
220 for (i = k = 0; i < bins; i++) {
221 if (cdf[i] < percent[j] / 100.0)
222 k = i;
223 else
224 break;
225 }
226 position[j] = xMin + (k * (xMax - xMin)) / bins;
227 }
228 free(hist);
229 return 1;
230}
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
Definition findMinMax.c:33
long make_histogram(double *hist, long n_bins, double lo, double hi, double *data, int64_t n_pts, long new_start)
Compiles a histogram from data points.

◆ compute_average()

long compute_average ( double * value,
double * data,
int64_t n )

Computes the average of an array of doubles.

Parameters
valuePointer to store the computed average value.
dataPointer to the array of doubles.
nNumber of elements in the array.
Returns
Returns 1 on success, 0 on failure.

Definition at line 152 of file median.c.

152 {
153 double sum;
154 int64_t i;
155
156 if (n <= 0)
157 return 0;
158
159 for (i = sum = 0; i < n; i++)
160 sum += data[i];
161 *value = sum / n;
162 return 1;
163}

◆ compute_median()

long compute_median ( double * value,
double * x,
long n )

Computes the median of an array of doubles.

Parameters
valuePointer to store the computed median value.
xPointer to the array of doubles.
nNumber of elements in the array.
Returns
Returns 1 on success, 0 on failure.

Definition at line 29 of file median.c.

29 {
30 static MDB_THREAD_LOCAL double *data = NULL;
31 static MDB_THREAD_LOCAL long last_n = 0;
32 long i;
33
34 if (n <= 0)
35 return 0;
36 if (n > last_n) {
37 data = trealloc(data, sizeof(*data) * n);
38 last_n = n;
39 }
40 for (i = 0; i < n; i++)
41 data[i] = x[i];
42 qsort((void *)data, n, sizeof(*data), double_cmpasc);
43 *value = data[n / 2];
44 return 1;
45}
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:190
int double_cmpasc(const void *a, const void *b)
Compare two doubles in ascending order.

◆ compute_middle()

long compute_middle ( double * value,
double * data,
long n )

Computes the middle value between the minimum and maximum of an array of doubles.

Parameters
valuePointer to store the computed middle value.
dataPointer to the array of doubles.
nNumber of elements in the array.
Returns
Returns 1 on success, 0 on failure.

Definition at line 173 of file median.c.

173 {
174 double min, max;
175 if (n <= 0)
176 return 0;
177
178 if (!find_min_max(&min, &max, data, n))
179 return 0;
180 *value = (min + max) / 2;
181 return 1;
182}

◆ compute_percentile()

long compute_percentile ( double * value,
double * x,
long n,
double percentile )

Computes a specific percentile of an array of doubles.

Parameters
valuePointer to store the computed percentile value.
xPointer to the array of doubles.
nNumber of elements in the array.
percentileThe desired percentile to compute (0-100).
Returns
Returns 1 on success, 0 on failure.

Definition at line 56 of file median.c.

56 {
57 static MDB_THREAD_LOCAL double *data = NULL;
58 static MDB_THREAD_LOCAL long last_n = 0;
59 long i;
60
61 if (n <= 0 || percentile < 0 || percentile > 100)
62 return 0;
63 if (n > last_n) {
64 data = trealloc(data, sizeof(*data) * n);
65 last_n = n;
66 }
67 for (i = 0; i < n; i++)
68 data[i] = x[i];
69 qsort((void *)data, n, sizeof(*data), double_cmpasc);
70 *value = data[(long)((n - 1) * (percentile / 100.0))];
71 return 1;
72}

◆ compute_percentiles()

long compute_percentiles ( double * position,
double * percent,
long positions,
double * x,
long n )

Computes multiple percentiles of an array of doubles.

Parameters
positionPointer to the array to store the computed percentile values.
percentPointer to the array of percentiles to compute (each value between 0-100).
positionsNumber of percentiles to compute.
xPointer to the array of doubles.
nNumber of elements in the array.
Returns
Returns 1 on success, 0 on failure.

Definition at line 84 of file median.c.

84 {
85 static MDB_THREAD_LOCAL double *data = NULL;
86 static MDB_THREAD_LOCAL long last_n = 0;
87 long ip;
88
89 if (n <= 0 || positions <= 0)
90 return 0;
91 for (ip = 0; ip < positions; ip++)
92 if (percent[ip] < 0 || percent[ip] > 100)
93 return 0;
94 if (n > last_n) {
95 data = trealloc(data, sizeof(*data) * n);
96 last_n = n;
97 }
98 memcpy((char *)data, (char *)x, sizeof(*x) * n);
99 qsort((void *)data, n, sizeof(*data), double_cmpasc);
100 for (ip = 0; ip < positions; ip++)
101 position[ip] = data[(long)((n - 1) * (percent[ip] / 100.0))];
102 return 1;
103}

◆ compute_percentiles_flagged()

long compute_percentiles_flagged ( double * position,
double * percent,
long positions,
double * x,
int32_t * keep,
int64_t n )

Computes multiple percentiles of an array of doubles, considering only flagged elements.

Parameters
positionPointer to the array to store the computed percentile values.
percentPointer to the array of percentiles to compute (each value between 0-100).
positionsNumber of percentiles to compute.
xPointer to the array of doubles.
keepPointer to the array of flags indicating which elements to include.
nNumber of elements in the array.
Returns
Returns 1 on success, 0 on failure.

Definition at line 116 of file median.c.

116 {
117 static MDB_THREAD_LOCAL double *data = NULL;
118 static MDB_THREAD_LOCAL int64_t last_n = 0;
119 int64_t ip, jp, count;
120
121 if (n <= 0 || positions <= 0)
122 return 0;
123 for (ip = 0; ip < positions; ip++)
124 if (percent[ip] < 0 || percent[ip] > 100)
125 return 0;
126 for (ip=count=0; ip<n; ip++)
127 if (keep[ip])
128 count++;
129 if (!count)
130 return 0;
131 if (count > last_n) {
132 data = trealloc(data, sizeof(*data) * count);
133 last_n = count;
134 }
135 for (ip=jp=0; ip<n; ip++)
136 if (keep[ip])
137 data[jp++] = x[ip];
138 qsort((void *)data, count, sizeof(*data), double_cmpasc);
139 for (ip = 0; ip < positions; ip++)
140 position[ip] = data[(long)((count - 1) * (percent[ip] / 100.0))];
141 return 1;
142}