xmode.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include "globals.h"
  5. #include "expression.h"
  6. #include "func_proto.h"
  7. /**********************************************************************
  8. mode(x1,x2,..,xn)
  9. return mode of arguments
  10. **********************************************************************/
  11. static int dcmp(const void *aa, const void *bb)
  12. {
  13. const double *a = aa;
  14. const double *b = bb;
  15. if (*a < *b)
  16. return -1;
  17. if (*a > *b)
  18. return 1;
  19. return 0;
  20. }
  21. static double mode(double *value, int argc)
  22. {
  23. double mode_v;
  24. int mode_n = 0;
  25. int i;
  26. qsort(value, argc, sizeof(double), dcmp);
  27. for (i = 0; i < argc;) {
  28. int n = 1;
  29. double v = value[i];
  30. for (i++; i < argc; i++) {
  31. if (value[i] != v)
  32. break;
  33. n++;
  34. }
  35. if (n < mode_n)
  36. continue;
  37. mode_v = v;
  38. mode_n = n;
  39. }
  40. return mode_v;
  41. }
  42. int f_mode(int argc, const int *argt, void **args)
  43. {
  44. static double *value;
  45. static int value_size;
  46. int size = argc * sizeof(double);
  47. int i, j;
  48. if (argc < 1)
  49. return E_ARG_LO;
  50. for (i = 1; i <= argc; i++)
  51. if (argt[i] != argt[0])
  52. return E_ARG_TYPE;
  53. if (size > value_size) {
  54. value_size = size;
  55. value = G_realloc(value, value_size);
  56. }
  57. switch (argt[argc]) {
  58. case CELL_TYPE:
  59. {
  60. CELL *res = args[0];
  61. CELL **argv = (CELL **) & args[1];
  62. for (i = 0; i < columns; i++) {
  63. int nv = 0;
  64. for (j = 0; j < argc && !nv; j++) {
  65. if (IS_NULL_C(&argv[j][i]))
  66. nv = 1;
  67. else
  68. value[j] = (double)argv[j][i];
  69. }
  70. if (nv)
  71. SET_NULL_C(&res[i]);
  72. else
  73. res[i] = (CELL) mode(value, argc);
  74. }
  75. return 0;
  76. }
  77. case FCELL_TYPE:
  78. {
  79. FCELL *res = args[0];
  80. FCELL **argv = (FCELL **) & args[1];
  81. for (i = 0; i < columns; i++) {
  82. int nv = 0;
  83. for (j = 0; j < argc && !nv; j++) {
  84. if (IS_NULL_F(&argv[j][i]))
  85. nv = 1;
  86. else
  87. value[j] = (double)argv[j][i];
  88. }
  89. if (nv)
  90. SET_NULL_F(&res[i]);
  91. else
  92. res[i] = (FCELL) mode(value, argc);
  93. }
  94. return 0;
  95. }
  96. case DCELL_TYPE:
  97. {
  98. DCELL *res = args[0];
  99. DCELL **argv = (DCELL **) & args[1];
  100. for (i = 0; i < columns; i++) {
  101. int nv = 0;
  102. for (j = 0; j < argc && !nv; j++) {
  103. if (IS_NULL_D(&argv[j][i]))
  104. nv = 1;
  105. else
  106. value[j] = (double)argv[j][i];
  107. }
  108. if (nv)
  109. SET_NULL_D(&res[i]);
  110. else
  111. res[i] = (DCELL) mode(value, argc);
  112. }
  113. return 0;
  114. }
  115. default:
  116. return E_INV_TYPE;
  117. }
  118. }