xmedian.c 2.7 KB

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