c_reassign.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*!
  2. \file cluster/c_reassign.c
  3. \brief Cluster library - Reassign cluster
  4. (C) 2001-2009 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Original author CERL
  8. */
  9. #include <math.h>
  10. #include <grass/cluster.h>
  11. /*!
  12. \brief ?
  13. \param C pointer to Cluster structure
  14. \param interrupted
  15. \return number of changes
  16. */
  17. int I_cluster_reassign(struct Cluster *C, int *interrupted)
  18. {
  19. double min, d, z;
  20. double q;
  21. int c, np;
  22. int old;
  23. int p, band, class;
  24. int changes;
  25. int first;
  26. changes = 0;
  27. for (c = 0; c < C->nclasses; c++) {
  28. C->countdiff[c] = 0;
  29. for (band = 0; band < C->nbands; band++)
  30. C->sumdiff[band][c] = 0;
  31. }
  32. min = HUGE_VAL;
  33. class = 0;
  34. for (p = 0; p < C->npoints; p++) {
  35. if (*interrupted)
  36. return 0;
  37. if (C->class[p] < 0) /* point to be ignored */
  38. continue;
  39. /* find minimum distance to center of all classes */
  40. first = 1;
  41. for (c = 0; c < C->nclasses; c++) {
  42. d = 0;
  43. np = C->count[c];
  44. if (np == 0)
  45. continue;
  46. for (band = 0; band < C->nbands; band++) {
  47. z = C->points[band][p] * np - C->sum[band][c];
  48. d += z * z;
  49. }
  50. d /= (np * np);
  51. if (first || (d < min)) {
  52. class = c;
  53. min = d;
  54. first = 0;
  55. }
  56. }
  57. if (C->class[p] != class) {
  58. old = C->class[p];
  59. C->class[p] = class;
  60. changes++;
  61. C->countdiff[class]++;
  62. C->countdiff[old]--;
  63. for (band = 0; band < C->nbands; band++) {
  64. q = C->points[band][p];
  65. C->sumdiff[band][class] += q;
  66. C->sumdiff[band][old] -= q;
  67. }
  68. }
  69. }
  70. if (changes) {
  71. for (c = 0; c < C->nclasses; c++) {
  72. C->count[c] += C->countdiff[c];
  73. for (band = 0; band < C->nbands; band++)
  74. C->sum[band][c] += C->sumdiff[band][c];
  75. }
  76. }
  77. return changes;
  78. }