c_exec.c 2.7 KB

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