123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /****************************************************************************
- *
- * MODULE: r.regression.line
- *
- * AUTHOR(S): Dr. Agustin Lobo
- * Markus Metz (conversion to C for speed)
- *
- * PURPOSE: Calculates linear regression from two raster maps:
- * y = a + b*x
- *
- * COPYRIGHT: (C) 2010 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include <grass/raster.h>
- int main(int argc, char *argv[])
- {
- unsigned int r, c, rows, cols; /* totals */
- int map1_fd, map2_fd;
- double sumX, sumY, sumsqX, sumsqY, sumXY;
- double meanX, meanY, varX, varY, sdX, sdY;
- double A, B, R, F;
- long count = 0;
- DCELL *map1_buf, *map2_buf, map1_val, map2_val;
- char *name;
- struct Option *input_map1, *input_map2, *output_opt;
- struct Flag *shell_style;
- struct Cell_head region;
- struct GModule *module;
- G_gisinit(argv[0]);
- module = G_define_module();
- G_add_keyword(_("raster"));
- G_add_keyword(_("statistics"));
- G_add_keyword(_("regression"));
- module->description =
- _("Calculates linear regression from two raster maps: y = a + b*x.");
- /* Define the different options */
- input_map1 = G_define_standard_option(G_OPT_R_MAP);
- input_map1->key = "mapx";
- input_map1->description = (_("Map for x coefficient"));
- input_map2 = G_define_standard_option(G_OPT_R_MAP);
- input_map2->key = "mapy";
- input_map2->description = (_("Map for y coefficient"));
- output_opt = G_define_standard_option(G_OPT_F_OUTPUT);
- output_opt->key = "output";
- output_opt->required = NO;
- output_opt->description =
- (_("ASCII file for storing regression coefficients (output to screen if file not specified)."));
- shell_style = G_define_flag();
- shell_style->key = 'g';
- shell_style->description = _("Print in shell script style");
- if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
- name = output_opt->answer;
- if (name != NULL && strcmp(name, "-") != 0) {
- if (NULL == freopen(name, "w", stdout)) {
- G_fatal_error(_("Unable to open file <%s> for writing"), name);
- }
- }
- G_get_window(®ion);
- rows = region.rows;
- cols = region.cols;
- /* open maps */
- map1_fd = Rast_open_old(input_map1->answer, "");
- map2_fd = Rast_open_old(input_map2->answer, "");
- map1_buf = Rast_allocate_d_buf();
- map2_buf = Rast_allocate_d_buf();
- sumX = sumY = sumsqX = sumsqY = sumXY = 0.0;
- meanX = meanY = varX = varY = sdX = sdY = 0.0;
- for (r = 0; r < rows; r++) {
- G_percent(r, rows, 2);
- Rast_get_d_row(map1_fd, map1_buf, r);
- Rast_get_d_row(map2_fd, map2_buf, r);
- for (c = 0; c < cols; c++) {
- map1_val = map1_buf[c];
- map2_val = map2_buf[c];
- if (Rast_is_d_null_value(&map1_val) ||
- Rast_is_d_null_value(&map2_val))
- continue;
- sumX += map1_val;
- sumY += map2_val;
- sumsqX += map1_val * map1_val;
- sumsqY += map2_val * map2_val;
- sumXY += map1_val * map2_val;
- count++;
- }
- }
- Rast_close(map1_fd);
- Rast_close(map2_fd);
- G_free(map1_buf);
- G_free(map2_buf);
- B = (sumXY - sumX * sumY / count) / (sumsqX - sumX * sumX / count);
- R = (sumXY - sumX * sumY / count) /
- sqrt((sumsqX - sumX * sumX / count) * (sumsqY - sumY * sumY / count));
- meanX = sumX / count;
- sumsqX = sumsqX / count;
- varX = sumsqX - (meanX * meanX);
- sdX = sqrt(varX);
- meanY = sumY / count;
- sumsqY = sumsqY / count;
- varY = sumsqY - (meanY * meanY);
- sdY = sqrt(varY);
- A = meanY - B * meanX;
- F = R * R / ((1 - R * R) / (count - 2));
- if (shell_style->answer) {
- fprintf(stdout, "a=%f\n", A);
- fprintf(stdout, "b=%f\n", B);
- fprintf(stdout, "R=%f\n", R);
- fprintf(stdout, "N=%ld\n", count);
- fprintf(stdout, "F=%f\n", F);
- fprintf(stdout, "meanX=%f\n", meanX);
- fprintf(stdout, "sdX=%f\n", sdX);
- fprintf(stdout, "meanY=%f\n", meanY);
- fprintf(stdout, "sdY=%f\n", sdY);
- }
- else {
- fprintf(stdout, "y = a + b*x\n");
- fprintf(stdout, " a (Offset): %f\n", A);
- fprintf(stdout, " b (Gain): %f\n", B);
- fprintf(stdout, " R (sumXY - sumX*sumY/N): %f\n", R);
- fprintf(stdout, " N (Number of elements): %ld\n", count);
- fprintf(stdout, " F (F-test significance): %f\n", F);
- fprintf(stdout, " meanX (Mean of map1): %f\n", meanX);
- fprintf(stdout, " sdX (Standard deviation of map1): %f\n", sdX);
- fprintf(stdout, " meanY (Mean of map2): %f\n", meanY);
- fprintf(stdout, " sdY (Standard deviation of map2): %f\n", sdY);
- }
- exit(EXIT_SUCCESS);
- }
|