xnmode.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. double mode_v;
  22. int mode_n = 0;
  23. int i;
  24. qsort(value, argc, sizeof(double), dcmp);
  25. for (i = 0; i < argc;) {
  26. int n = 1;
  27. double v = value[i];
  28. for (i++; i < argc; i++) {
  29. if (value[i] != v)
  30. break;
  31. n++;
  32. }
  33. if (n < mode_n)
  34. continue;
  35. mode_v = v;
  36. mode_n = n;
  37. }
  38. return mode_v;
  39. }
  40. int f_nmode(int argc, const int *argt, void **args)
  41. {
  42. static double *value;
  43. static int value_size;
  44. int size = argc * sizeof(double);
  45. int i, j;
  46. if (argc < 1)
  47. return E_ARG_LO;
  48. for (i = 1; i <= argc; i++)
  49. if (argt[i] != argt[0])
  50. return E_ARG_TYPE;
  51. if (size > value_size) {
  52. value_size = size;
  53. value = G_realloc(value, value_size);
  54. }
  55. switch (argt[argc]) {
  56. case CELL_TYPE:
  57. {
  58. CELL *res = args[0];
  59. CELL **argv = (CELL **) & args[1];
  60. for (i = 0; i < columns; i++) {
  61. int n = 0;
  62. for (j = 0; j < argc; j++) {
  63. if (IS_NULL_C(&argv[j][i]))
  64. continue;
  65. value[n++] = (double)argv[j][i];
  66. }
  67. if (!n)
  68. SET_NULL_C(&res[i]);
  69. else
  70. res[i] = (CELL) mode(value, n);
  71. }
  72. return 0;
  73. }
  74. case FCELL_TYPE:
  75. {
  76. FCELL *res = args[0];
  77. FCELL **argv = (FCELL **) & args[1];
  78. for (i = 0; i < columns; i++) {
  79. int n = 0;
  80. for (j = 0; j < argc; j++) {
  81. if (IS_NULL_F(&argv[j][i]))
  82. continue;
  83. value[n++] = (double)argv[j][i];
  84. }
  85. if (!n)
  86. SET_NULL_F(&res[i]);
  87. else
  88. res[i] = (FCELL) mode(value, n);
  89. }
  90. return 0;
  91. }
  92. case DCELL_TYPE:
  93. {
  94. DCELL *res = args[0];
  95. DCELL **argv = (DCELL **) & args[1];
  96. for (i = 0; i < columns; i++) {
  97. int n = 0;
  98. for (j = 0; j < argc; j++) {
  99. if (IS_NULL_D(&argv[j][i]))
  100. continue;
  101. value[n++] = (double)argv[j][i];
  102. }
  103. if (!n)
  104. SET_NULL_D(&res[i]);
  105. else
  106. res[i] = (DCELL) mode(value, n);
  107. }
  108. return 0;
  109. }
  110. default:
  111. return E_INV_TYPE;
  112. }
  113. }