GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
xnmode.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_nmode
(
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
n = 0;
87
88
for
(j = 0; j < argc; j++) {
89
if
(IS_NULL_C(&argv[j][i]))
90
continue
;
91
value[n++] = (double)argv[j][i];
92
}
93
94
if
(!n)
95
SET_NULL_C(&res[i]);
96
else
97
res[i] = (CELL)mode(value, n);
98
}
99
if
(use_heap) {
100
G_free
(value);
101
}
102
return
0;
103
}
104
case
FCELL_TYPE: {
105
FCELL *res = args[0];
106
FCELL **argv = (FCELL **)&args[1];
107
108
for
(i = 0; i <
columns
; i++) {
109
int
n = 0;
110
111
for
(j = 0; j < argc; j++) {
112
if
(IS_NULL_F(&argv[j][i]))
113
continue
;
114
value[n++] = (double)argv[j][i];
115
}
116
117
if
(!n)
118
SET_NULL_F(&res[i]);
119
else
120
res[i] = (FCELL)mode(value, n);
121
}
122
if
(use_heap) {
123
G_free
(value);
124
}
125
return
0;
126
}
127
case
DCELL_TYPE: {
128
DCELL *res = args[0];
129
DCELL **argv = (DCELL **)&args[1];
130
131
for
(i = 0; i <
columns
; i++) {
132
int
n = 0;
133
134
for
(j = 0; j < argc; j++) {
135
if
(IS_NULL_D(&argv[j][i]))
136
continue
;
137
value[n++] = (double)argv[j][i];
138
}
139
140
if
(!n)
141
SET_NULL_D(&res[i]);
142
else
143
res[i] = (DCELL)mode(value, n);
144
}
145
if
(use_heap) {
146
G_free
(value);
147
}
148
return
0;
149
}
150
default
:
151
if
(use_heap) {
152
G_free
(value);
153
}
154
return
E_INV_TYPE;
155
}
156
}
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_nmode
int f_nmode(int argc, const int *argt, void **args)
Definition
xnmode.c:60
calc
xnmode.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0