GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
xmode.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_mode(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 nv = 0;
83
84 for (j = 0; j < argc && !nv; j++) {
85 if (IS_NULL_C(&argv[j][i]))
86 nv = 1;
87 else
88 value[j] = (double)argv[j][i];
89 }
90
91 if (nv)
92 SET_NULL_C(&res[i]);
93 else
94 res[i] = (CELL)mode(value, argc);
95 }
96 return 0;
97 }
98 case FCELL_TYPE: {
99 FCELL *res = args[0];
100 FCELL **argv = (FCELL **)&args[1];
101
102 for (i = 0; i < columns; i++) {
103 int nv = 0;
104
105 for (j = 0; j < argc && !nv; j++) {
106 if (IS_NULL_F(&argv[j][i]))
107 nv = 1;
108 else
109 value[j] = (double)argv[j][i];
110 }
111
112 if (nv)
113 SET_NULL_F(&res[i]);
114 else
115 res[i] = (FCELL)mode(value, argc);
116 }
117 return 0;
118 }
119 case DCELL_TYPE: {
120 DCELL *res = args[0];
121 DCELL **argv = (DCELL **)&args[1];
122
123 for (i = 0; i < columns; i++) {
124 int nv = 0;
125
126 for (j = 0; j < argc && !nv; j++) {
127 if (IS_NULL_D(&argv[j][i]))
128 nv = 1;
129 else
130 value[j] = (double)argv[j][i];
131 }
132
133 if (nv)
134 SET_NULL_D(&res[i]);
135 else
136 res[i] = (DCELL)mode(value, argc);
137 }
138 return 0;
139 }
140 default:
141 return E_INV_TYPE;
142 }
143}
int columns
Definition calc.c:11
double b
int f_mode(int argc, const int *argt, void **args)
Definition xmode.c:57