c_exec.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*!
  2. \file cluster/c_exec.c
  3. \brief Cluster library - Exectute clusterring
  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 <grass/cluster.h>
  10. #include <grass/glocale.h>
  11. /*!
  12. \param C pointer to Cluster structure
  13. \param maxclass maximum number of classes
  14. \param iterations maximum number of iterations
  15. \param convergence percentage of points stable
  16. \param separation minimum distance between class centroids
  17. \param min_class_size minimum size of class
  18. \param checkpoint routine to be called at various steps
  19. \param interrupted boolean to check for interrupt
  20. \return 0 ok
  21. \return -1 out of memory
  22. \return -2 interrupted
  23. \return 1 not enough data points
  24. */
  25. int I_cluster_exec(struct Cluster *C, int maxclass, int iterations,
  26. double convergence,
  27. double separation, int min_class_size,
  28. int (*checkpoint) (), int *interrupted)
  29. {
  30. int changes;
  31. /* set interrupted to false */
  32. *interrupted = 0;
  33. /* check for valid inputs */
  34. if (C->npoints < 2) {
  35. G_warning(_("Not enough data points (%d) in cluster"), C->npoints);
  36. return 1;
  37. }
  38. /* check other parms */
  39. if (maxclass < 0)
  40. maxclass = 1;
  41. C->nclasses = maxclass;
  42. if (min_class_size <= 0)
  43. min_class_size = 17;
  44. if (min_class_size < 2)
  45. min_class_size = 2;
  46. if (iterations <= 0)
  47. iterations = 20;
  48. if (convergence <= 0.0)
  49. convergence = 98.0;
  50. if (separation < 0.0)
  51. separation = 0.5;
  52. /* allocate memory */
  53. if (!I_cluster_exec_allocate(C))
  54. return -1;
  55. /* generate class means */
  56. I_cluster_means(C);
  57. if (checkpoint)
  58. (*checkpoint) (C, 1);
  59. /* now assign points to nearest class */
  60. I_cluster_assign(C, interrupted);
  61. if (*interrupted)
  62. return -2;
  63. I_cluster_sum2(C);
  64. if (checkpoint)
  65. (*checkpoint) (C, 2);
  66. /* get rid of empty classes now */
  67. I_cluster_reclass(C, 1);
  68. for (C->iteration = 1;; C->iteration++) {
  69. if (*interrupted)
  70. return -2;
  71. changes = 0;
  72. /* re-assign points to nearest class */
  73. changes = I_cluster_reassign(C, interrupted);
  74. if (*interrupted)
  75. return -2;
  76. /* if too many points have changed class, re-assign points */
  77. C->percent_stable = (C->npoints - changes) * 100.0;
  78. C->percent_stable /= (double)C->npoints;
  79. if (checkpoint)
  80. (*checkpoint) (C, 3);
  81. if (C->iteration >= iterations)
  82. break;
  83. if (C->percent_stable < convergence)
  84. continue;
  85. /* otherwise merge non-distinct classes */
  86. if (I_cluster_distinct(C, separation))
  87. break;
  88. if (checkpoint)
  89. (*checkpoint) (C, 4);
  90. I_cluster_merge(C);
  91. }
  92. /* get rid of small classes */
  93. I_cluster_reclass(C, min_class_size);
  94. I_cluster_sum2(C);
  95. /* compute the resulting signatures */
  96. I_cluster_signatures(C);
  97. return 0;
  98. }