GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
xmode.c
Go to the documentation of this file.
1
#include <stdlib.h>
2
#include <stdbool.h>
3
4
#include <grass/gis.h>
5
#include <grass/raster.h>
6
#include <grass/calc.h>
7
8
/**********************************************************************
9
mode(x1,x2,..,xn)
10
return mode of arguments
11
**********************************************************************/
12
13
#define SIZE_THRESHOLD 32
14
15
static
int
dcmp(
const
void
*aa,
const
void
*bb)
16
{
17
const
double
*a = aa;
18
const
double
*
b
= bb;
19
20
if
(*a < *
b
)
21
return
-1;
22
if
(*a > *
b
)
23
return
1;
24
return
0;
25
}
26
27
static
double
mode(
double
*value,
int
argc)
28
{
29
/* Nota:
30
* It might be safer for to return nan or inf in case the input is empty,
31
* but it is a misuse of the function, so the return value is sort of
32
* undefined in that case.
33
*/
34
double
mode_v = 0.0;
35
int
mode_n = 0;
36
int
i;
37
38
qsort(value, argc,
sizeof
(
double
), dcmp);
39
40
for
(i = 0; i < argc;) {
41
int
n = 1;
42
double
v = value[i];
43
44
for
(i++; i < argc; i++) {
45
if
(value[i] != v)
46
break
;
47
n++;
48
}
49
50
if
(n < mode_n)
51
continue
;
52
53
mode_v = v;
54
mode_n = n;
55
}
56
57
return
mode_v;
58
}
59
60
int
f_mode
(
int
argc,
const
int
*argt,
void
**args)
61
{
62
double
stack_value[
SIZE_THRESHOLD
];
63
double
*value = stack_value;
64
bool
use_heap =
false
;
65
int
size = argc *
sizeof
(double);
66
int
i, j;
67
68
if
(argc < 1)
69
return
E_ARG_LO;
70
71
for
(i = 1; i <= argc; i++)
72
if
(argt[i] != argt[0])
73
return
E_ARG_TYPE;
74
75
if
(argc >
SIZE_THRESHOLD
) {
76
value = G_malloc(size);
77
use_heap =
true
;
78
}
79
80
switch
(argt[argc]) {
81
case
CELL_TYPE: {
82
CELL *res = args[0];
83
CELL **argv = (CELL **)&args[1];
84
85
for
(i = 0; i <
columns
; i++) {
86
int
nv = 0;
87
88
for
(j = 0; j < argc && !nv; j++) {
89
if
(IS_NULL_C(&argv[j][i]))
90
nv = 1;
91
else
92
value[j] = (double)argv[j][i];
93
}
94
95
if
(nv)
96
SET_NULL_C(&res[i]);
97
else
98
res[i] = (CELL)mode(value, argc);
99
}
100
if
(use_heap) {
101
G_free
(value);
102
}
103
return
0;
104
}
105
case
FCELL_TYPE: {
106
FCELL *res = args[0];
107
FCELL **argv = (FCELL **)&args[1];
108
109
for
(i = 0; i <
columns
; i++) {
110
int
nv = 0;
111
112
for
(j = 0; j < argc && !nv; j++) {
113
if
(IS_NULL_F(&argv[j][i]))
114
nv = 1;
115
else
116
value[j] = (double)argv[j][i];
117
}
118
119
if
(nv)
120
SET_NULL_F(&res[i]);
121
else
122
res[i] = (FCELL)mode(value, argc);
123
}
124
if
(use_heap) {
125
G_free
(value);
126
}
127
return
0;
128
}
129
case
DCELL_TYPE: {
130
DCELL *res = args[0];
131
DCELL **argv = (DCELL **)&args[1];
132
133
for
(i = 0; i <
columns
; i++) {
134
int
nv = 0;
135
136
for
(j = 0; j < argc && !nv; j++) {
137
if
(IS_NULL_D(&argv[j][i]))
138
nv = 1;
139
else
140
value[j] = (double)argv[j][i];
141
}
142
143
if
(nv)
144
SET_NULL_D(&res[i]);
145
else
146
res[i] = (DCELL)mode(value, argc);
147
}
148
if
(use_heap) {
149
G_free
(value);
150
}
151
return
0;
152
}
153
default
:
154
if
(use_heap) {
155
G_free
(value);
156
}
157
return
E_INV_TYPE;
158
}
159
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
columns
int columns
Definition
calc.c:11
b
double b
Definition
driver/set_window.c:5
SIZE_THRESHOLD
#define SIZE_THRESHOLD
Definition
xmedian.c:13
f_mode
int f_mode(int argc, const int *argt, void **args)
Definition
xmode.c:60
calc
xmode.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0