GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 /*************************************************************** 00003 * 00004 * I_cluster_exec (C, maxclass, iterations, 00005 * convergence, separation, min_class_size, 00006 * checkpoint, interrupted) 00007 * 00008 * maxclass maximum number of classes 00009 * iterations maximum number of iterations 00010 * convergence percentage of points stable 00011 * separation minimum distance between class centroids 00012 * checkpoint routine to be called at various steps 00013 * interrupted boolean to check for interrupt 00014 * 00015 * returns: 00016 * 0 ok 00017 * -1 out of memory 00018 * -2 interrupted 00019 * 1 not enough data points 00020 *************************************************************/ 00021 #include <grass/cluster.h> 00022 00023 int I_cluster_exec(struct Cluster *C, int maxclass, int iterations, 00024 double convergence, 00025 double separation, int min_class_size, 00026 int (*checkpoint) (), int *interrupted) 00027 { 00028 int changes; 00029 00030 /* set interrupted to false */ 00031 *interrupted = 0; 00032 00033 /* check for valid inputs */ 00034 if (C->npoints < 2) { 00035 fprintf(stderr, "cluster: not enough data points (%d)\n", C->npoints); 00036 return 1; 00037 } 00038 00039 /* check other parms */ 00040 if (maxclass < 0) 00041 maxclass = 1; 00042 C->nclasses = maxclass; 00043 00044 if (min_class_size <= 0) 00045 min_class_size = 17; 00046 if (min_class_size < 2) 00047 min_class_size = 2; 00048 00049 if (iterations <= 0) 00050 iterations = 20; 00051 if (convergence <= 0.0) 00052 convergence = 98.0; 00053 if (separation < 0.0) 00054 separation = 0.5; 00055 00056 00057 /* allocate memory */ 00058 if (!I_cluster_exec_allocate(C)) 00059 return -1; 00060 00061 00062 /* generate class means */ 00063 I_cluster_means(C); 00064 if (checkpoint) 00065 (*checkpoint) (C, 1); 00066 00067 /* now assign points to nearest class */ 00068 I_cluster_assign(C, interrupted); 00069 if (*interrupted) 00070 return -2; 00071 I_cluster_sum2(C); 00072 if (checkpoint) 00073 (*checkpoint) (C, 2); 00074 00075 /* get rid of empty classes now */ 00076 I_cluster_reclass(C, 1); 00077 00078 for (C->iteration = 1;; C->iteration++) { 00079 if (*interrupted) 00080 return -2; 00081 00082 changes = 0; 00083 00084 /* re-assign points to nearest class */ 00085 00086 changes = I_cluster_reassign(C, interrupted); 00087 if (*interrupted) 00088 return -2; 00089 00090 /* if too many points have changed class, re-assign points */ 00091 C->percent_stable = (C->npoints - changes) * 100.0; 00092 C->percent_stable /= (double)C->npoints; 00093 00094 if (checkpoint) 00095 (*checkpoint) (C, 3); 00096 00097 if (C->iteration >= iterations) 00098 break; 00099 00100 if (C->percent_stable < convergence) 00101 continue; 00102 00103 /* otherwise merge non-distinct classes */ 00104 00105 if (I_cluster_distinct(C, separation)) 00106 break; 00107 00108 if (checkpoint) 00109 (*checkpoint) (C, 4); 00110 00111 I_cluster_merge(C); 00112 } 00113 00114 /* get rid of small classes */ 00115 I_cluster_reclass(C, min_class_size); 00116 I_cluster_sum2(C); 00117 00118 /* compute the resulting signatures */ 00119 I_cluster_signatures(C); 00120 00121 00122 return 0; 00123 }