123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- /*!
- \file cluster/c_reassign.c
-
- \brief Cluster library - Reassign cluster
-
- (C) 2001-2009 by the GRASS Development Team
-
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
-
- \author Original author CERL
- */
- #include <math.h>
- #include <grass/cluster.h>
- /*!
- \brief ?
- \param C pointer to Cluster structure
- \param interrupted
- \return number of changes
- */
- int I_cluster_reassign(struct Cluster *C, int *interrupted)
- {
- double min, d, z;
- double q;
- int c, np;
- int old;
- int p, band, class;
- int changes;
- int first;
- changes = 0;
- for (c = 0; c < C->nclasses; c++) {
- C->countdiff[c] = 0;
- for (band = 0; band < C->nbands; band++)
- C->sumdiff[band][c] = 0;
- }
- min = HUGE_VAL;
- class = 0;
- for (p = 0; p < C->npoints; p++) {
- if (*interrupted)
- return 0;
- if (C->class[p] < 0) /* point to be ignored */
- continue;
- /* find minimum distance to center of all classes */
- first = 1;
- for (c = 0; c < C->nclasses; c++) {
- d = 0;
- np = C->count[c];
- if (np == 0)
- continue;
- for (band = 0; band < C->nbands; band++) {
- z = C->points[band][p] * np - C->sum[band][c];
- d += z * z;
- }
- d /= (np * np);
- if (first || (d < min)) {
- class = c;
- min = d;
- first = 0;
- }
- }
- if (C->class[p] != class) {
- old = C->class[p];
- C->class[p] = class;
- changes++;
- C->countdiff[class]++;
- C->countdiff[old]--;
- for (band = 0; band < C->nbands; band++) {
- q = C->points[band][p];
- C->sumdiff[band][class] += q;
- C->sumdiff[band][old] -= q;
- }
- }
- }
- if (changes) {
- for (c = 0; c < C->nclasses; c++) {
- C->count[c] += C->countdiff[c];
- for (band = 0; band < C->nbands; band++)
- C->sum[band][c] += C->sumdiff[band][c];
- }
- }
- return changes;
- }
|