o_sdev.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <grass/gis.h>
  6. #include <grass/raster.h>
  7. #include <grass/glocale.h>
  8. #include "method.h"
  9. #define MEM 1024
  10. /* function prototypes */
  11. static int s_dev(double *, int, double *);
  12. int o_sdev(const char *basemap, const char *covermap, const char *outputmap,
  13. int usecats, struct Categories *cats)
  14. {
  15. struct Popen stats_child, reclass_child;
  16. FILE *stats, *reclass;
  17. int first, mem, i, count;
  18. long basecat, covercat, catb, catc;
  19. double value, sdev, x;
  20. double *tab;
  21. mem = MEM * sizeof(double);
  22. tab = (double *)G_malloc(mem);
  23. stats = run_stats(&stats_child, basemap, covermap, "-cn");
  24. reclass = run_reclass(&reclass_child, basemap, outputmap);
  25. first = 1;
  26. while (read_stats(stats, &basecat, &covercat, &value)) {
  27. if (first) {
  28. first = 0;
  29. catb = basecat;
  30. catc = covercat;
  31. i = 0;
  32. count = 0;
  33. }
  34. if (basecat != catb) {
  35. s_dev(tab, count, &sdev);
  36. fprintf(reclass, "%ld = %ld %f\n", catb, catb, sdev);
  37. catb = basecat;
  38. catc = covercat;
  39. count = 0;
  40. }
  41. if (usecats)
  42. sscanf(Rast_get_c_cat((CELL *) &covercat, cats), "%lf", &x);
  43. else
  44. x = covercat;
  45. for (i = 0; i < value; i++) {
  46. if (count * sizeof(double) >= mem) {
  47. mem += MEM * sizeof(double);
  48. tab = (double *)G_realloc(tab, mem);
  49. /* fprintf(stderr,"MALLOC: %d KB needed\n",(int)(mem/1024)); */
  50. }
  51. tab[count++] = x;
  52. }
  53. }
  54. if (first) {
  55. catb = catc = 0;
  56. }
  57. s_dev(tab, count, &sdev);
  58. fprintf(reclass, "%ld = %ld %f\n", catb, catb, sdev);
  59. G_debug(5, "%ld = %ld %f\n", catb, catb, sdev);
  60. G_popen_close(&stats_child);
  61. G_popen_close(&reclass_child);
  62. return 0;
  63. }
  64. /***********************************************************************
  65. *
  66. * Given an array of data[1...n], this routine returns its standard
  67. * deviation sdev.
  68. *
  69. ************************************************************************/
  70. static int s_dev(double *data, int n, double *sdev)
  71. {
  72. double ave, var, ep, s;
  73. int i;
  74. if (n < 1) {
  75. G_warning(_("o_var: No data in array"));
  76. return (1);
  77. }
  78. *sdev = 0.0;
  79. var = 0.0;
  80. ep = 0.0;
  81. s = 0.0;
  82. for (i = 0; i < n; i++) /* First pass to get the mean */
  83. s += data[i];
  84. ave = s / n;
  85. for (i = 0; i < n; i++) {
  86. s = data[i] - ave;
  87. var += s * s;
  88. ep += s;
  89. }
  90. var = (var - ep * ep / n) / (n - 1);
  91. *sdev = sqrt(var);
  92. return (0);
  93. }