-
Notifications
You must be signed in to change notification settings - Fork 110
/
p_median.c
74 lines (60 loc) · 1.65 KB
/
p_median.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <string.h>
#include <pal.h>
static void swap(PTYPE *lhs, PTYPE *rhs)
{
PTYPE tmp = *lhs;
*lhs = *rhs;
*rhs = tmp;
}
static unsigned int median_partition(PTYPE *a,
unsigned int left,
unsigned int right,
unsigned int pivot_index)
{
unsigned int store_index = left;
unsigned int i = left;
PTYPE pivot = a[pivot_index];
swap(&a[pivot_index], &a[right]);
for (; i < right; ++i) {
if (a[i] < pivot)
swap(&a[i], &a[store_index++]);
}
swap(&a[store_index], &a[right]);
return store_index;
}
/**
*
* Calculates the median value of input vector 'a'.
*
* @param a Pointer to input vector
*
* @param c Pointer to output scalar
*
* @param n Size of 'a' vector.
*
* @return None
*
*/
void PSYM(p_median)(const PTYPE *a, PTYPE *c, int n)
{
unsigned int left = 0;
unsigned int median_index = (n - 1) >> 1;
PTYPE median_value = PCONST(0.0);
PTYPE search_a[n];
memcpy(search_a, a, sizeof(PTYPE) * n);
for (; median_index <= (n >> 1); ++median_index) {
unsigned int right = n - 1;
unsigned int pivot_index = 0;
do {
pivot_index =
median_partition(search_a, left, right, (left + right) >> 1);
if (pivot_index > median_index) {
right = pivot_index - 1;
} else {
left = pivot_index + 1;
}
} while (pivot_index != median_index);
median_value += search_a[pivot_index];
}
*c = (n % 2 ? median_value : median_value * 0.5);
}