c_reg.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include <grass/gis.h>
  2. #include <grass/raster.h>
  3. #define REGRESSION_SLOPE 0
  4. #define REGRESSION_OFFSET 1
  5. #define REGRESSION_COEFF_DET 2
  6. static void regression(DCELL * result, DCELL * values, int n, int which)
  7. {
  8. DCELL xsum, ysum;
  9. DCELL xbar, ybar;
  10. DCELL numer, denom, denom2;
  11. int count;
  12. int i;
  13. xsum = ysum = 0.0;
  14. count = 0;
  15. for (i = 0; i < n; i++) {
  16. if (Rast_is_d_null_value(&values[i]))
  17. continue;
  18. xsum += i;
  19. ysum += values[i];
  20. count++;
  21. }
  22. if (count < 2) {
  23. Rast_set_d_null_value(result, 1);
  24. return;
  25. }
  26. xbar = xsum / count;
  27. ybar = ysum / count;
  28. numer = 0.0;
  29. for (i = 0; i < n; i++)
  30. if (!Rast_is_d_null_value(&values[i]))
  31. numer += i * values[i];
  32. numer -= count * xbar * ybar;
  33. denom = 0.0;
  34. for (i = 0; i < n; i++)
  35. if (!Rast_is_d_null_value(&values[i]))
  36. denom += (DCELL) i *i;
  37. denom -= count * xbar * xbar;
  38. if (which == REGRESSION_COEFF_DET) {
  39. denom2 = 0.0;
  40. for (i = 0; i < n; i++)
  41. if (!Rast_is_d_null_value(&values[i]))
  42. denom2 += values[i] * values[i];
  43. denom2 -= count * ybar * ybar;
  44. }
  45. switch (which) {
  46. case REGRESSION_SLOPE:
  47. *result = numer / denom;
  48. break;
  49. case REGRESSION_OFFSET:
  50. *result = ybar - xbar * numer / denom;
  51. break;
  52. case REGRESSION_COEFF_DET:
  53. *result = (numer * numer) / (denom * denom2);
  54. break;
  55. default:
  56. Rast_set_d_null_value(result, 1);
  57. break;
  58. }
  59. /* Check for NaN */
  60. if (*result != *result)
  61. Rast_set_d_null_value(result, 1);
  62. }
  63. void c_reg_m(DCELL * result, DCELL * values, int n, const void *closure)
  64. {
  65. regression(result, values, n, REGRESSION_SLOPE);
  66. }
  67. void c_reg_c(DCELL * result, DCELL * values, int n, const void *closure)
  68. {
  69. regression(result, values, n, REGRESSION_OFFSET);
  70. }
  71. void c_reg_r2(DCELL * result, DCELL * values, int n, const void *closure)
  72. {
  73. regression(result, values, n, REGRESSION_COEFF_DET);
  74. }
  75. static void regression_w(DCELL * result, DCELL(*values)[2], int n, int which)
  76. {
  77. DCELL xsum, ysum;
  78. DCELL xbar, ybar;
  79. DCELL numer, denom, denom2;
  80. int count;
  81. int i;
  82. xsum = ysum = 0.0;
  83. count = 0;
  84. for (i = 0; i < n; i++) {
  85. if (Rast_is_d_null_value(&values[i][0]))
  86. continue;
  87. xsum += i * values[i][1];
  88. ysum += values[i][0] * values[i][1];
  89. count += values[i][1];
  90. }
  91. if (count < 2) {
  92. Rast_set_d_null_value(result, 1);
  93. return;
  94. }
  95. xbar = xsum / count;
  96. ybar = ysum / count;
  97. numer = 0.0;
  98. for (i = 0; i < n; i++)
  99. if (!Rast_is_d_null_value(&values[i][0]))
  100. numer += i * values[i][0] * values[i][1];
  101. numer -= count * xbar * ybar;
  102. denom = 0.0;
  103. for (i = 0; i < n; i++)
  104. if (!Rast_is_d_null_value(&values[i][0]))
  105. denom += (DCELL) i *i * values[i][1];
  106. denom -= count * xbar * xbar;
  107. if (which == REGRESSION_COEFF_DET) {
  108. denom2 = 0.0;
  109. for (i = 0; i < n; i++)
  110. if (!Rast_is_d_null_value(&values[i][0]))
  111. denom2 += values[i][0] * values[i][0] * values[i][1];
  112. denom2 -= count * ybar * ybar;
  113. }
  114. switch (which) {
  115. case REGRESSION_SLOPE:
  116. *result = numer / denom;
  117. break;
  118. case REGRESSION_OFFSET:
  119. *result = ybar - xbar * numer / denom;
  120. break;
  121. case REGRESSION_COEFF_DET:
  122. *result = (numer * numer) / (denom * denom2);
  123. break;
  124. default:
  125. Rast_set_d_null_value(result, 1);
  126. break;
  127. }
  128. /* Check for NaN */
  129. if (*result != *result)
  130. Rast_set_d_null_value(result, 1);
  131. }
  132. void w_reg_m(DCELL * result, DCELL(*values)[2], int n, const void *closure)
  133. {
  134. regression_w(result, values, n, REGRESSION_SLOPE);
  135. }
  136. void w_reg_c(DCELL * result, DCELL(*values)[2], int n, const void *closure)
  137. {
  138. regression_w(result, values, n, REGRESSION_OFFSET);
  139. }
  140. void w_reg_r2(DCELL * result, DCELL(*values)[2], int n, const void *closure)
  141. {
  142. regression_w(result, values, n, REGRESSION_COEFF_DET);
  143. }