GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
xnmedian.c
Go to the documentation of this file.
1#include <stdlib.h>
2
3#include <grass/gis.h>
4#include <grass/raster.h>
5#include <grass/raster.h>
6#include <grass/calc.h>
7
8/**********************************************************************
9median(x1,x2,..,xn)
10 return median of arguments
11**********************************************************************/
12
13static int icmp(const void *aa, const void *bb)
14{
15 const CELL *a = aa;
16 const CELL *b = bb;
17
18 return *a - *b;
19}
20
21static int fcmp(const void *aa, const void *bb)
22{
23 const FCELL *a = aa;
24 const FCELL *b = bb;
25
26 if (*a < *b)
27 return -1;
28 if (*a > *b)
29 return 1;
30 return 0;
31}
32
33static int dcmp(const void *aa, const void *bb)
34{
35 const DCELL *a = aa;
36 const DCELL *b = bb;
37
38 if (*a < *b)
39 return -1;
40 if (*a > *b)
41 return 1;
42 return 0;
43}
44
45int f_nmedian(int argc, const int *argt, void **args)
46{
47 static void *array;
48 static int alloc;
49 int size = argc * Rast_cell_size(argt[0]);
50 int i, j;
51
52 if (argc < 1)
53 return E_ARG_LO;
54
55 for (i = 1; i <= argc; i++)
56 if (argt[i] != argt[0])
57 return E_ARG_TYPE;
58
59 if (size > alloc) {
60 alloc = size;
61 array = G_realloc(array, size);
62 }
63
64 switch (argt[0]) {
65 case CELL_TYPE: {
66 CELL *res = args[0];
67 CELL **argv = (CELL **)&args[1];
68 CELL *a = array;
69 CELL a1;
70 CELL *resc;
71
72 for (i = 0; i < columns; i++) {
73 int n = 0;
74
75 for (j = 0; j < argc; j++) {
76 if (IS_NULL_C(&argv[j][i]))
77 continue;
78 a[n++] = argv[j][i];
79 }
80
81 resc = &res[i];
82
83 if (!n)
84 SET_NULL_C(resc);
85 else {
86 qsort(a, n, sizeof(CELL), icmp);
87 *resc = a[n / 2];
88 if ((n & 1) == 0) {
89 a1 = a[(n - 1) / 2];
90 if (*resc != a1)
91 *resc = (*resc + a1) / 2;
92 }
93 }
94 }
95
96 return 0;
97 }
98 case FCELL_TYPE: {
99 FCELL *res = args[0];
100 FCELL **argv = (FCELL **)&args[1];
101 FCELL *a = array;
102 FCELL a1;
103 FCELL *resc;
104
105 for (i = 0; i < columns; i++) {
106 int n = 0;
107
108 for (j = 0; j < argc; j++) {
109 if (IS_NULL_F(&argv[j][i]))
110 continue;
111 a[n++] = argv[j][i];
112 }
113
114 resc = &res[i];
115
116 if (!n)
117 SET_NULL_F(resc);
118 else {
119 qsort(a, n, sizeof(FCELL), fcmp);
120 *resc = a[n / 2];
121 if ((n & 1) == 0) {
122 a1 = a[(n - 1) / 2];
123 if (*resc != a1)
124 *resc = (*resc + a1) / 2;
125 }
126 }
127 }
128
129 return 0;
130 }
131 case DCELL_TYPE: {
132 DCELL *res = args[0];
133 DCELL **argv = (DCELL **)&args[1];
134 DCELL *a = array;
135 DCELL a1;
136 DCELL *resc;
137
138 for (i = 0; i < columns; i++) {
139 int n = 0;
140
141 for (j = 0; j < argc; j++) {
142 if (IS_NULL_D(&argv[j][i]))
143 continue;
144 a[n++] = argv[j][i];
145 }
146
147 resc = &res[i];
148
149 if (!n)
150 SET_NULL_D(resc);
151 else {
152 qsort(a, n, sizeof(DCELL), dcmp);
153 *resc = a[n / 2];
154 if ((n & 1) == 0) {
155 a1 = a[(n - 1) / 2];
156 if (*resc != a1)
157 *resc = (*resc + a1) / 2;
158 }
159 }
160 }
161
162 return 0;
163 }
164 default:
165 return E_INV_TYPE;
166 }
167}
int columns
Definition calc.c:11
double b
int f_nmedian(int argc, const int *argt, void **args)
Definition xnmedian.c:45