File: c_exec.c

package info (click to toggle)
grass 6.0.2-6
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 40,044 kB
  • ctags: 31,303
  • sloc: ansic: 321,125; tcl: 25,676; sh: 11,176; cpp: 10,098; makefile: 5,025; fortran: 1,846; yacc: 493; lex: 462; perl: 133; sed: 1
file content (124 lines) | stat: -rw-r--r-- 2,738 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/***************************************************************
 *
 * I_cluster_exec (C, maxclass, iterations,
 *               convergence, separation, min_class_size,
 *               checkpoint, interrupted)
 *
 *  maxclass       maximum number of classes
 *  iterations     maximum number of iterations
 *  convergence    percentage of points stable
 *  separation     minimum distance between class centroids
 *  checkpoint     routine to be called at various steps
 *  interrupted    boolean to check for interrupt
 *
 * returns:
 *   0 ok
 *  -1 out of memory
 *  -2 interrupted
 *   1 not enough data points
 *************************************************************/
#include "imagery.h"

int I_cluster_exec (
    struct Cluster *C,int maxclass,int iterations,
    double convergence,
    double separation,int min_class_size,
    int (*checkpoint)(),
    int *interrupted)
{
    int changes;

/* set interrupted to false */
    *interrupted = 0;

/* check for valid inputs */
    if (C->npoints < 2)
    {
	fprintf (stderr, "cluster: not enough data points (%d)\n",
	    C->npoints);
	return 1;
    }

/* check other parms */
    if (maxclass < 0)
	maxclass = 1;
    C->nclasses = maxclass;

    if (min_class_size <= 0)
	min_class_size = 17;
    if (min_class_size < 2)
	min_class_size = 2;

    if (iterations <= 0)
	iterations = 20;
    if (convergence <= 0.0)
	convergence = 98.0;
    if (separation < 0.0)
	separation = 0.5;


/* allocate memory */
    if (!I_cluster_exec_allocate(C))
	return -1;


/* generate class means */
    I_cluster_means (C);
    if (checkpoint)
    	(*checkpoint) (C,1);

/* now assign points to nearest class */
    I_cluster_assign (C,interrupted);
    if (*interrupted) return -2;
    I_cluster_sum2(C);
    if (checkpoint)
    	(*checkpoint) (C,2);

/* get rid of empty classes now */
    I_cluster_reclass (C,1);

    for (C->iteration = 1; ; C->iteration++)
    {
	if (*interrupted) return -2;

	changes = 0;

/* re-assign points to nearest class */

	changes = I_cluster_reassign (C,interrupted);
	if (*interrupted) return -2;

/* if too many points have changed class, re-assign points */
	C->percent_stable = (C->npoints-changes) * 100.0;
	C->percent_stable /= (double) C->npoints;

	if (checkpoint)
	    (*checkpoint) (C,3);

	if (C->iteration >= iterations)
	    break;

	if (C->percent_stable < convergence)
	    continue;

/* otherwise merge non-distinct classes */

	if (I_cluster_distinct (C,separation))
	    break;

	if (checkpoint)
	    (*checkpoint) (C,4);

	I_cluster_merge (C) ;
    }

/* get rid of small classes */
    I_cluster_reclass (C,min_class_size);
    I_cluster_sum2(C);

/* compute the resulting signatures */
    I_cluster_signatures (C);


    return 0;
}