| Bsoft 2.0.5 Bernard's software package

cluster.cpp
Go to the documentation of this file.
1
9 #include "cluster.h"
10 #include "utilities.h"
11
12 //#ifndef DBL_MAX
13 //#define DBL_MAX 1.7976e308
14 //#endif
15
16 // Declaration of global variables
17 extern int verbose; // Level of output to the screen
18
28 long* k_means(long n, float* data, long k)
29 {
30 long i, j, ik, jk, imax(100), nun[k], change(1);
31 double min, max, d, dmin, avg[k], sum[k];
32 long* sel = new long[n];
33
34 min = max = data[0];
35 for ( j=0; j<n; j++ ) {
36 sel[j] = k;
37 if ( min > data[j] ) min = data[j];
38 if ( max < data[j] ) max = data[j];
39 }
40
41 for ( ik=0; ik<k; ik++ ) avg[ik] = (ik + 0.5)*(max - min)/k + min;
42
43 // cout << avg[0] << tab << avg[1] << endl;
44
45 for ( i=0; i<imax && change; i++ ) {
46 change = 0;
47 for ( ik=0; ik<k; ik++ ) {
48 sum[ik] = 0;
49 nun[ik] = 0;
50 }
51 for ( j=0; j<n; j++ ) {
52 dmin = 1e37;
53 for ( ik=jk=0; ik<k; ik++ ) {
54 d = fabs(data[j] - avg[ik]);
55 if ( dmin > d ) {
56 dmin = d;
57 jk = ik;
58 }
59 }
60 sum[jk] += data[j];
61 nun[jk]++;
62 change += (sel[j] != jk);
63 sel[j] = jk;
64 }
65 for ( ik=0; ik<k; ik++ ) {
66 if ( nun[ik] ) avg[ik] = sum[ik]/nun[ik];
67 else avg[ik] = (ik + 0.5)*(max - min)/k + min;
68 }
69 // cout << i << tab << avg[0] << tab << nun[0] << tab << avg[1] << tab << nun[1] << endl;
70 }
71
72 if ( verbose & VERB_PROCESS ) {
73 cout << "K-means clustering:" << endl;
74 for ( ik=0; ik<k; ik++ )
75 cout << "Class " << ik << ": " << avg[ik] << " (" << nun[ik] << ")" << endl;
76 cout << endl;
77 }
78
79 return sel;
80 }
81
102 long* affin_prop_clustering(Matrix s, long maxit, long convit, double lambda, long& ncluster)
103 {
104 if ( s.rows() < 2 ) {
105 cerr << "Error: No input similarity matrix!" << endl;
106 return NULL;
107 }
108
109 if ( lambda < 0.1 ) lambda = 0.1;
110 if ( lambda > 0.9 ) lambda = 0.9;
111 if ( convit < 2 ) convit = 2;
112 if ( maxit < 2*convit ) maxit = 2*convit;
113
114 int n = s.rows();
115
116 char t;
117 long it, cit, i, j, k, nc;
118 double v;
119
120 double* a = new double[n*n];
121 double* r = new double[n*n];
122 double* mx1 = new double[n];
123 double* mx2 = new double[n];
124 double* srp = new double[n];
125 char* c = new char[n];
126 long* idx = new long[n];
127
128 // for ( i=0; i<n*n; i++ ) s[i] = s[i] + (1e-16*s[i] + 1e-306)*(rand()/((double)RAND_MAX+1));
129
130 for ( i=0; i<n*n; i++ ) a[i] = r[i] = 0;
131 for ( j=0; j<n; j++ ) c[j] = 0;
132
133 // The loop exits on two conditions:
134 // 1. Exceeding the set maximum number of iterations
135 // 2. No change in the cluster solution for the set number of convergence iterations
136 // (i.e., when cit >= convit)
137 for ( it=cit=0; it<maxit && cit<convit; it++, cit++ ) {
138 // Calculate responsibilities
139 for ( i=j=0; j<n; j++ ) {
140 mx1[j] = mx2[j] = -DBL_MAX;
141 for ( k=0; k<n; k++, i++ ) {
142 v = a[i] + s[j][k];
143 if ( mx1[j] < v ) {
144 mx2[j] = mx1[j];
145 mx1[j] = v;
146 } else if ( mx2[j] < v ) {
147 mx2[j] = v;
148 }
149 }
150 }
151 for ( i=j=0; j<n; j++ ) {
152 for ( k=0; k<n; k++, i++ ) {
153 v = a[i] + s[j][k];
154 if ( v == mx1[j] ) v = mx2[j];
155 else v = mx1[j];
156 r[i] = lambda*r[i] + (1-lambda)*(s[j][k] - v);
157 }
158 }
159 // Calculate availabilities
160 for( k=0; k<n; k++ ) srp[k] = 0;
161 for ( i=j=0; j<n; j++ )
162 for ( k=0; k<n; k++, i++ )
163 if( r[i] > 0 ) srp[k] += r[i];
164 for( i=k=0; k<n; k++, i+=n+1 ) if ( r[i] < 0 ) srp[k] += r[i];
165 for ( i=j=0; j<n; j++ ) {
166 for ( k=0; k<n; k++, i++ ) if ( j != k ) {
167 v = srp[k];
168 if( r[i] > 0 ) v -= r[i];
169 if ( v < 0 ) a[i] = lambda*a[i]+(1-lambda)*v;
170 else a[i] = lambda*a[i];
171 }
172 }
173 for( i=k=0; k<n; k++, i+=n+1 )
174 a[i] = lambda*a[i] + (1-lambda)*(srp[k] - r[i]);
175 // Update exemplars and test exit conditions
176 for( i=j=0, nc=0; j<n; j++, i+=n+1 ) {
177 if ( a[i] + r[i] > 0 ) t=1; else t=0;
178 if ( c[j] != t ) cit = 0; // Reset the convergence counter
179 c[j] = t;
180 nc += c[j];
181 }
182 if ( nc < 1 ) cit = 0; // Reset the convergence counter
183 if ( verbose & VERB_FULL )
184 cout << it << tab << nc << endl;
185 }
186
187 double netsim, dpsim(0), expref(0);
188 for( j=0, nc=0; j<n; j++ ) nc += c[j];
189
190 if ( nc > 0 ) {
191 for( i=j=0; j<n; j++ ) {
192 for ( k=0; k<n; k++, i++ ) {
193 if ( c[k] ) a[i] = 0;
194 else a[i] = -DBL_MAX;
195 }
196 }
197 for ( i=j=0; j<n; j++ ) {
198 mx1[j] = -DBL_MAX;
199 for ( k=0; k<n; k++, i++ ) {
200 v = a[i] + s[j][k];
201 if ( mx1[j] < v ) {
202 mx1[j] = v;
203 idx[j] = k;
204 }
205 }
206 if( c[j] ) idx[j] = j;
207 }
208 dpsim = expref = 0;
209 for( i=j=0; j<n; j++ ) {
210 for ( k=0; k<n; k++, i++ ) {
211 if ( idx[j] == k ) {
212 if ( j == k ) expref += s[j][k];
213 else dpsim += s[j][k];
214 }
215 }
216 }
217 }
218
219 netsim = dpsim + expref;
220
221 long* m = new long[n];
222
223 for ( j=0; j<n; j++ ) m[j] = 0;
224
225 for ( j=0; j<n; j++ ) m[idx[j]]++;
226
227 for ( j=ncluster=0; j<n; j++ ) if ( m[j] ) ncluster++;
228
229 if ( verbose & VERB_RESULT ) {
230 cout << "Number of points: " << n << endl;
231 cout << "Number of iterations: " << it << endl;
232 cout << "Number of clusters: " << nc << endl;
233 cout << "Fitness (net similarity): " << netsim << endl;
234 cout << " Similarities to exemplars: " << dpsim << endl;
235 cout << " Preferences of exemplars: " << expref << endl << endl;
236 cout << "Cluster\tNumber" << endl;
237 for ( j=0; j<n; j++ ) if ( j == idx[j] )
238 cout << j+1 << tab << m[j] << endl;
239 cout << endl;
240 cout << "Point\tCluster\tSimilarity" << endl;
241 for ( j=0; j<n; j++ )
242 cout << j+1 << tab << idx[j]+1 << tab << s[idx[j]][j] << endl;
243 cout << endl;
244 }
245
246 delete[] a;
247 delete[] r;
248 delete[] mx1;
249 delete[] mx2;
250 delete[] srp;
251 delete[] c;
252 delete[] m;
253
254 return idx;
255 }
256
Matrix::rows
long rows()
Definition: Matrix.h:153
utilities.h
Header file for general utilities.
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
affin_prop_clustering
long * affin_prop_clustering(Matrix s, long maxit, long convit, double lambda, long &ncluster)
Generate clusters from a similarity matrix using affinity propagation.
Definition: cluster.cpp:102
k_means
long * k_means(long n, float *data, long k)
Generate clusters using a K-means algorithm.
Definition: cluster.cpp:28
verbose
int verbose
VERB_RESULT
#define VERB_RESULT
Definition: utilities.h:105
Matrix
Definition: Matrix.h:21
cluster.h
Header file for clustering functions.
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21