main.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /****************************************************************************
  2. *
  3. * MODULE: r.regression.line
  4. *
  5. * AUTHOR(S): Dr. Agustin Lobo
  6. * Markus Metz (conversion to C for speed)
  7. *
  8. * PURPOSE: Calculates linear regression from two raster maps:
  9. * y = a + b*x
  10. *
  11. * COPYRIGHT: (C) 2010 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <math.h>
  21. #include <string.h>
  22. #include <grass/gis.h>
  23. #include <grass/glocale.h>
  24. #include <grass/raster.h>
  25. int main(int argc, char *argv[])
  26. {
  27. unsigned int r, c, rows, cols; /* totals */
  28. int map1_fd, map2_fd;
  29. double sumX, sumY, sumsqX, sumsqY, sumXY;
  30. double meanX, meanY, varX, varY, sdX, sdY;
  31. double A, B, R, F;
  32. long count = 0;
  33. DCELL *map1_buf, *map2_buf, map1_val, map2_val;
  34. char *name;
  35. struct Option *input_map1, *input_map2, *output_opt;
  36. struct Flag *shell_style;
  37. struct Cell_head region;
  38. struct GModule *module;
  39. G_gisinit(argv[0]);
  40. module = G_define_module();
  41. G_add_keyword(_("raster"));
  42. G_add_keyword(_("statistics"));
  43. G_add_keyword(_("regression"));
  44. module->description =
  45. _("Calculates linear regression from two raster maps: y = a + b*x.");
  46. /* Define the different options */
  47. input_map1 = G_define_standard_option(G_OPT_R_MAP);
  48. input_map1->key = "mapx";
  49. input_map1->description = (_("Map for x coefficient"));
  50. input_map2 = G_define_standard_option(G_OPT_R_MAP);
  51. input_map2->key = "mapy";
  52. input_map2->description = (_("Map for y coefficient"));
  53. output_opt = G_define_standard_option(G_OPT_F_OUTPUT);
  54. output_opt->key = "output";
  55. output_opt->required = NO;
  56. output_opt->description =
  57. (_("ASCII file for storing regression coefficients (output to screen if file not specified)."));
  58. shell_style = G_define_flag();
  59. shell_style->key = 'g';
  60. shell_style->description = _("Print in shell script style");
  61. if (G_parser(argc, argv))
  62. exit(EXIT_FAILURE);
  63. name = output_opt->answer;
  64. if (name != NULL && strcmp(name, "-") != 0) {
  65. if (NULL == freopen(name, "w", stdout)) {
  66. G_fatal_error(_("Unable to open file <%s> for writing"), name);
  67. }
  68. }
  69. G_get_window(&region);
  70. rows = region.rows;
  71. cols = region.cols;
  72. /* open maps */
  73. map1_fd = Rast_open_old(input_map1->answer, "");
  74. map2_fd = Rast_open_old(input_map2->answer, "");
  75. map1_buf = Rast_allocate_d_buf();
  76. map2_buf = Rast_allocate_d_buf();
  77. sumX = sumY = sumsqX = sumsqY = sumXY = 0.0;
  78. meanX = meanY = varX = varY = sdX = sdY = 0.0;
  79. for (r = 0; r < rows; r++) {
  80. G_percent(r, rows, 2);
  81. Rast_get_d_row(map1_fd, map1_buf, r);
  82. Rast_get_d_row(map2_fd, map2_buf, r);
  83. for (c = 0; c < cols; c++) {
  84. map1_val = map1_buf[c];
  85. map2_val = map2_buf[c];
  86. if (Rast_is_d_null_value(&map1_val) ||
  87. Rast_is_d_null_value(&map2_val))
  88. continue;
  89. sumX += map1_val;
  90. sumY += map2_val;
  91. sumsqX += map1_val * map1_val;
  92. sumsqY += map2_val * map2_val;
  93. sumXY += map1_val * map2_val;
  94. count++;
  95. }
  96. }
  97. Rast_close(map1_fd);
  98. Rast_close(map2_fd);
  99. G_free(map1_buf);
  100. G_free(map2_buf);
  101. B = (sumXY - sumX * sumY / count) / (sumsqX - sumX * sumX / count);
  102. R = (sumXY - sumX * sumY / count) /
  103. sqrt((sumsqX - sumX * sumX / count) * (sumsqY - sumY * sumY / count));
  104. meanX = sumX / count;
  105. sumsqX = sumsqX / count;
  106. varX = sumsqX - (meanX * meanX);
  107. sdX = sqrt(varX);
  108. meanY = sumY / count;
  109. sumsqY = sumsqY / count;
  110. varY = sumsqY - (meanY * meanY);
  111. sdY = sqrt(varY);
  112. A = meanY - B * meanX;
  113. F = R * R / ((1 - R * R) / (count - 2));
  114. if (shell_style->answer) {
  115. fprintf(stdout, "a=%f\n", A);
  116. fprintf(stdout, "b=%f\n", B);
  117. fprintf(stdout, "R=%f\n", R);
  118. fprintf(stdout, "N=%ld\n", count);
  119. fprintf(stdout, "F=%f\n", F);
  120. fprintf(stdout, "meanX=%f\n", meanX);
  121. fprintf(stdout, "sdX=%f\n", sdX);
  122. fprintf(stdout, "meanY=%f\n", meanY);
  123. fprintf(stdout, "sdY=%f\n", sdY);
  124. }
  125. else {
  126. fprintf(stdout, "y = a + b*x\n");
  127. fprintf(stdout, " a (Offset): %f\n", A);
  128. fprintf(stdout, " b (Gain): %f\n", B);
  129. fprintf(stdout, " R (sumXY - sumX*sumY/N): %f\n", R);
  130. fprintf(stdout, " N (Number of elements): %ld\n", count);
  131. fprintf(stdout, " F (F-test significance): %f\n", F);
  132. fprintf(stdout, " meanX (Mean of map1): %f\n", meanX);
  133. fprintf(stdout, " sdX (Standard deviation of map1): %f\n", sdX);
  134. fprintf(stdout, " meanY (Mean of map2): %f\n", meanY);
  135. fprintf(stdout, " sdY (Standard deviation of map2): %f\n", sdY);
  136. }
  137. exit(EXIT_SUCCESS);
  138. }