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