File: c_exec.c

package info (click to toggle)
grass 6.4.4-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 104,028 kB
  • ctags: 40,409
  • sloc: ansic: 419,980; python: 63,559; tcl: 46,692; cpp: 29,791; sh: 18,564; makefile: 7,000; xml: 3,505; yacc: 561; perl: 559; lex: 480; sed: 70; objc: 7
file content (123 lines) | stat: -rw-r--r-- 2,770 bytes parent folder | download | duplicates (3)
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

/***************************************************************
 *
 * 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 <grass/cluster.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;
}