GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
xnmode.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/calc.h>
6
7/**********************************************************************
8mode(x1,x2,..,xn)
9 return mode of arguments
10**********************************************************************/
11
12static int dcmp(const void *aa, const void *bb)
13{
14 const double *a = aa;
15 const double *b = bb;
16
17 if (*a < *b)
18 return -1;
19 if (*a > *b)
20 return 1;
21 return 0;
22}
23
24static double mode(double *value, int argc)
25{
26 /* Nota:
27 * It might be safer for to return nan or inf in case the input is empty,
28 * but it is a misuse of the function, so the return value is sort of
29 * undefined in that case.
30 */
31 double mode_v = 0.0;
32 int mode_n = 0;
33 int i;
34
35 qsort(value, argc, sizeof(double), dcmp);
36
37 for (i = 0; i < argc;) {
38 int n = 1;
39 double v = value[i];
40
41 for (i++; i < argc; i++) {
42 if (value[i] != v)
43 break;
44 n++;
45 }
46
47 if (n < mode_n)
48 continue;
49
50 mode_v = v;
51 mode_n = n;
52 }
53
54 return mode_v;
55}
56
57int f_nmode(int argc, const int *argt, void **args)
58{
59 static double *value;
60 static int value_size;
61 int size = argc * sizeof(double);
62 int i, j;
63
64 if (argc < 1)
65 return E_ARG_LO;
66
67 for (i = 1; i <= argc; i++)
68 if (argt[i] != argt[0])
69 return E_ARG_TYPE;
70
71 if (size > value_size) {
72 value_size = size;
73 value = G_realloc(value, value_size);
74 }
75
76 switch (argt[argc]) {
77 case CELL_TYPE: {
78 CELL *res = args[0];
79 CELL **argv = (CELL **)&args[1];
80
81 for (i = 0; i < columns; i++) {
82 int n = 0;
83
84 for (j = 0; j < argc; j++) {
85 if (IS_NULL_C(&argv[j][i]))
86 continue;
87 value[n++] = (double)argv[j][i];
88 }
89
90 if (!n)
91 SET_NULL_C(&res[i]);
92 else
93 res[i] = (CELL)mode(value, n);
94 }
95 return 0;
96 }
97 case FCELL_TYPE: {
98 FCELL *res = args[0];
99 FCELL **argv = (FCELL **)&args[1];
100
101 for (i = 0; i < columns; i++) {
102 int n = 0;
103
104 for (j = 0; j < argc; j++) {
105 if (IS_NULL_F(&argv[j][i]))
106 continue;
107 value[n++] = (double)argv[j][i];
108 }
109
110 if (!n)
111 SET_NULL_F(&res[i]);
112 else
113 res[i] = (FCELL)mode(value, n);
114 }
115 return 0;
116 }
117 case DCELL_TYPE: {
118 DCELL *res = args[0];
119 DCELL **argv = (DCELL **)&args[1];
120
121 for (i = 0; i < columns; i++) {
122 int n = 0;
123
124 for (j = 0; j < argc; j++) {
125 if (IS_NULL_D(&argv[j][i]))
126 continue;
127 value[n++] = (double)argv[j][i];
128 }
129
130 if (!n)
131 SET_NULL_D(&res[i]);
132 else
133 res[i] = (DCELL)mode(value, n);
134 }
135 return 0;
136 }
137 default:
138 return E_INV_TYPE;
139 }
140}
int columns
Definition calc.c:11
double b
int f_nmode(int argc, const int *argt, void **args)
Definition xnmode.c:57