GRASS Programmer's Manual  6.4.2(2012)
c_exec.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines