xmode.c 2.6 KB

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