prt_mat.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include <grass/glocale.h>
  4. #include "kappa.h"
  5. #include "local_proto.h"
  6. static int longcomp(const void *aa, const void *bb);
  7. static int collapse(long *l, int n);
  8. void prn_error_mat(int out_cols, int hdr)
  9. {
  10. int i, j, k;
  11. int ncat1, ncat2;
  12. long x;
  13. long *clst;
  14. int num_panels, at_panel;
  15. int cndx, rndx;
  16. int first_col = 0, last_col = 0;
  17. int addflag = 0;
  18. int thisone;
  19. long t_row, t_col;
  20. long t_rowcount, grand_count;
  21. const char *mapone;
  22. FILE *fd;
  23. if (output != NULL) {
  24. if (hdr)
  25. fd = fopen(output, "w");
  26. else
  27. fd = fopen(output, "a");
  28. }
  29. else
  30. fd = stdout;
  31. if (fd == NULL) {
  32. G_fatal_error(_("Cannot open file <%s> to write cats and counts (error matrix)"),
  33. output);
  34. return;
  35. }
  36. else {
  37. /* get the cat lists */
  38. rlst = (long *)G_calloc(nstats * 2, sizeof(long));
  39. clst = (long *)G_calloc(nstats, sizeof(long));
  40. for (i = 0; i < nstats; i++) {
  41. rlst[i] = Gstats[i].cats[0];
  42. clst[i] = Gstats[i].cats[1];
  43. }
  44. /* sort the cat lists */
  45. qsort(rlst, nstats, sizeof(long), longcomp);
  46. qsort(clst, nstats, sizeof(long), longcomp);
  47. /* remove repeated cats */
  48. ncat1 = collapse(rlst, nstats);
  49. ncat2 = collapse(clst, nstats);
  50. /* copy clst to the end of rlst, remove repeated cats, and free unused memory */
  51. for (i = 0; i < ncat2; i++)
  52. rlst[ncat1 + i] = clst[i];
  53. qsort(rlst, ncat1 + ncat2, sizeof(long), longcomp);
  54. ncat = collapse(rlst, ncat1 + ncat2);
  55. rlst = (long *)G_realloc(rlst, ncat * sizeof(long));
  56. G_free(clst);
  57. /* allocate matrix and fill in with cats' value */
  58. matr = (long *)G_malloc(ncat * ncat * sizeof(long));
  59. for (i = 0; i < ncat * ncat; i++)
  60. matr[i] = 0;
  61. for (i = 0; i < nstats; i++) {
  62. for (j = 0; j < ncat; j++)
  63. if (rlst[j] == Gstats[i].cats[0])
  64. break;
  65. for (k = 0; k < ncat; k++)
  66. if (rlst[k] == Gstats[i].cats[1])
  67. break;
  68. /* matrix: reference in columns, classification in rows */
  69. matr[j * ncat + k] = Gstats[i].count;
  70. }
  71. /* format and print out the error matrix in panels */
  72. out_cols = (out_cols == 132) ? 9 : 5;
  73. num_panels = ncat / out_cols;
  74. if (ncat % out_cols)
  75. num_panels++;
  76. t_rowcount = 0;
  77. fprintf(fd, "\nError Matrix\n");
  78. for (at_panel = 0; at_panel < num_panels; at_panel++) {
  79. first_col = at_panel * out_cols;
  80. last_col = first_col + out_cols;
  81. if (last_col >= ncat) {
  82. last_col = ncat;
  83. }
  84. /* determine whether room available for row total at the end of last panel */
  85. addflag = 0;
  86. if (at_panel == (num_panels - 1) &&
  87. (last_col - first_col) < (out_cols - 1)) {
  88. addflag = 1;
  89. }
  90. /* panel line */
  91. fprintf(fd, "Panel #%d of %d\n", at_panel + 1, num_panels);
  92. /* name line */
  93. fprintf(fd, "\t\t\t MAP1\n");
  94. /* cat line */
  95. fprintf(fd, " cat#\t");
  96. for (cndx = first_col; cndx < last_col; cndx++)
  97. fprintf(fd, "%ld\t", rlst[cndx]);
  98. if (addflag)
  99. fprintf(fd, "Row Sum");
  100. fprintf(fd, "\n");
  101. /* body of the matrix */
  102. mapone = "MAP2";
  103. for (rndx = 0; rndx < ncat; rndx++) {
  104. if (*(mapone) != '\0')
  105. fprintf(fd, " %c %5ld\t", *(mapone)++, rlst[rndx]);
  106. else
  107. fprintf(fd, " %5ld\t", rlst[rndx]);
  108. /* entries */
  109. for (cndx = first_col; cndx < last_col; cndx++) {
  110. thisone = (ncat * rndx) + cndx;
  111. fprintf(fd, "%ld\t", matr[thisone]);
  112. }
  113. /* row marginal summation */
  114. if (addflag) {
  115. t_row = 0;
  116. for (k = 0; k < ncat; k++)
  117. t_row += matr[rndx * ncat + k];
  118. t_rowcount += t_row;
  119. fprintf(fd, "%ld", t_row);
  120. }
  121. fprintf(fd, "\n");
  122. }
  123. /* column marginal summation */
  124. fprintf(fd, "Col Sum\t\t");
  125. for (cndx = first_col; cndx < last_col; cndx++) {
  126. t_col = 0;
  127. x = cndx;
  128. for (k = 0; k < ncat; k++) {
  129. t_col += matr[x];
  130. x += ncat;
  131. }
  132. fprintf(fd, "%ld\t", t_col);
  133. }
  134. /* grand total */
  135. if (addflag)
  136. fprintf(fd, "%ld", t_rowcount);
  137. fprintf(fd, "\n\n");
  138. }
  139. /* Marginal summation if no room at the end of the last panel */
  140. if (!addflag) {
  141. fprintf(fd, "cat#\tRow Sum\n");
  142. mapone = layers[1].name;
  143. t_row = 0;
  144. t_rowcount = 0;
  145. grand_count = 0;
  146. for (rndx = 0; rndx < ncat; rndx++) {
  147. if (*(mapone) != '\0')
  148. fprintf(fd, "%c %5ld", *(mapone)++, rlst[rndx]);
  149. else
  150. fprintf(fd, " %5ld", rlst[rndx]);
  151. for (cndx = first_col; cndx < last_col; cndx++) {
  152. thisone = (ncat * rndx) + cndx;
  153. fprintf(fd, " %9ld ", matr[thisone]);
  154. t_row += matr[thisone];
  155. }
  156. t_rowcount += t_row;
  157. grand_count += t_rowcount;
  158. fprintf(fd, "%9ld\n", t_rowcount);
  159. }
  160. fprintf(fd, "%9ld\n", grand_count);
  161. }
  162. G_free(matr);
  163. if (output != NULL)
  164. fclose(fd);
  165. }
  166. }
  167. /* remove repeated values */
  168. static int collapse(long *l, int n)
  169. {
  170. long *c;
  171. int m;
  172. c = l;
  173. m = 1;
  174. while (n-- > 0) {
  175. if (*c != *l) {
  176. c++;
  177. *c = *l;
  178. m++;
  179. }
  180. l++;
  181. }
  182. return m;
  183. }
  184. static int longcomp(const void *aa, const void *bb)
  185. {
  186. const long *a = aa;
  187. const long *b = bb;
  188. return (*a - *b);
  189. }