GRASS Programmer's Manual  6.4.2(2012)
c_reassign.c
Go to the documentation of this file.
00001 #include <math.h>
00002 #include <grass/cluster.h>
00003 
00004 int I_cluster_reassign(struct Cluster *C, int *interrupted)
00005 {
00006     double min, d, z;
00007     double q;
00008     int c, np;
00009     int old;
00010     int p, band, class;
00011     int changes;
00012     int first;
00013 
00014     changes = 0;
00015     for (c = 0; c < C->nclasses; c++) {
00016         C->countdiff[c] = 0;
00017         for (band = 0; band < C->nbands; band++)
00018             C->sumdiff[band][c] = 0;
00019     }
00020 
00021     min = HUGE_VAL;
00022     class = 0;
00023     for (p = 0; p < C->npoints; p++) {
00024         if (*interrupted)
00025             return 0;
00026         if (C->class[p] < 0)    /* point to be ignored */
00027             continue;
00028 
00029         /* find minimum distance to center of all classes */
00030         first = 1;
00031         for (c = 0; c < C->nclasses; c++) {
00032             d = 0;
00033             np = C->count[c];
00034             if (np == 0)
00035                 continue;
00036             for (band = 0; band < C->nbands; band++) {
00037                 z = C->points[band][p] * np - C->sum[band][c];
00038                 d += z * z;
00039             }
00040             d /= (np * np);
00041 
00042             if (first || (d < min)) {
00043                 class = c;
00044                 min = d;
00045                 first = 0;
00046             }
00047         }
00048 
00049         if (C->class[p] != class) {
00050             old = C->class[p];
00051             C->class[p] = class;
00052             changes++;
00053 
00054             C->countdiff[class]++;
00055             C->countdiff[old]--;
00056 
00057             for (band = 0; band < C->nbands; band++) {
00058                 q = C->points[band][p];
00059                 C->sumdiff[band][class] += q;
00060                 C->sumdiff[band][old] -= q;
00061             }
00062         }
00063     }
00064 
00065     if (changes) {
00066         for (c = 0; c < C->nclasses; c++) {
00067             C->count[c] += C->countdiff[c];
00068             for (band = 0; band < C->nbands; band++)
00069                 C->sum[band][c] += C->sumdiff[band][c];
00070         }
00071     }
00072 
00073     return changes;
00074 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines