GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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  double mode_v;
28  int mode_n = 0;
29  int i;
30 
31  qsort(value, argc, sizeof(double), dcmp);
32 
33  for (i = 0; i < argc;) {
34  int n = 1;
35  double v = value[i];
36 
37  for (i++; i < argc; i++) {
38  if (value[i] != v)
39  break;
40  n++;
41  }
42 
43  if (n < mode_n)
44  continue;
45 
46  mode_v = v;
47  mode_n = n;
48  }
49 
50  return mode_v;
51 }
52 
53 int f_mode(int argc, const int *argt, void **args)
54 {
55  static double *value;
56  static int value_size;
57  int size = argc * sizeof(double);
58  int i, j;
59 
60  if (argc < 1)
61  return E_ARG_LO;
62 
63  for (i = 1; i <= argc; i++)
64  if (argt[i] != argt[0])
65  return E_ARG_TYPE;
66 
67  if (size > value_size) {
68  value_size = size;
69  value = G_realloc(value, value_size);
70  }
71 
72  switch (argt[argc]) {
73  case CELL_TYPE:
74  {
75  CELL *res = args[0];
76  CELL **argv = (CELL **) & args[1];
77 
78  for (i = 0; i < columns; i++) {
79  int nv = 0;
80 
81  for (j = 0; j < argc && !nv; j++) {
82  if (IS_NULL_C(&argv[j][i]))
83  nv = 1;
84  else
85  value[j] = (double)argv[j][i];
86  }
87 
88  if (nv)
89  SET_NULL_C(&res[i]);
90  else
91  res[i] = (CELL) mode(value, argc);
92  }
93  return 0;
94  }
95  case FCELL_TYPE:
96  {
97  FCELL *res = args[0];
98  FCELL **argv = (FCELL **) & args[1];
99 
100  for (i = 0; i < columns; i++) {
101  int nv = 0;
102 
103  for (j = 0; j < argc && !nv; j++) {
104  if (IS_NULL_F(&argv[j][i]))
105  nv = 1;
106  else
107  value[j] = (double)argv[j][i];
108  }
109 
110  if (nv)
111  SET_NULL_F(&res[i]);
112  else
113  res[i] = (FCELL) mode(value, argc);
114  }
115  return 0;
116  }
117  case DCELL_TYPE:
118  {
119  DCELL *res = args[0];
120  DCELL **argv = (DCELL **) & args[1];
121 
122  for (i = 0; i < columns; i++) {
123  int nv = 0;
124 
125  for (j = 0; j < argc && !nv; j++) {
126  if (IS_NULL_D(&argv[j][i]))
127  nv = 1;
128  else
129  value[j] = (double)argv[j][i];
130  }
131 
132  if (nv)
133  SET_NULL_D(&res[i]);
134  else
135  res[i] = (DCELL) mode(value, argc);
136  }
137  return 0;
138  }
139  default:
140  return E_INV_TYPE;
141  }
142 }
#define CELL_TYPE
Definition: raster.h:11
#define SET_NULL_C(x)
Definition: calc.h:32
double DCELL
Definition: gis.h:603
#define IS_NULL_F(x)
Definition: calc.h:29
int f_mode(int argc, const int *argt, void **args)
Definition: xmode.c:53
#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:604
#define IS_NULL_D(x)
Definition: calc.h:30
int CELL
Definition: gis.h:602
#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