GRASS Programmer's Manual
6.4.2(2012)
|
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 }