comparison dsp/segmentation/cluster_melt.c @ 505:930b5b0f707d

Merge branch 'codestyle-and-tidy'
author Chris Cannam <cannam@all-day-breakfast.com>
date Wed, 05 Jun 2019 12:55:15 +0100
parents d48276a3ae24
children
comparison
equal deleted inserted replaced
471:e3335cb213da 505:930b5b0f707d
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
1 /* 2 /*
2 * cluster.c 3 * cluster.c
3 * cluster_melt 4 * cluster_melt
4 * 5 *
5 * Created by Mark Levy on 21/02/2006. 6 * Created by Mark Levy on 21/02/2006.
19 20
20 #define DEFAULT_LAMBDA 0.02; 21 #define DEFAULT_LAMBDA 0.02;
21 #define DEFAULT_LIMIT 20; 22 #define DEFAULT_LIMIT 20;
22 23
23 double kldist(double* a, double* b, int n) { 24 double kldist(double* a, double* b, int n) {
24 /* NB assume that all a[i], b[i] are non-negative 25 /* NB assume that all a[i], b[i] are non-negative
25 because a, b represent probability distributions */ 26 because a, b represent probability distributions */
26 double q, d; 27 double q, d;
27 int i; 28 int i;
28 29
29 d = 0; 30 d = 0;
30 for (i = 0; i < n; i++) 31 for (i = 0; i < n; i++) {
31 { 32 q = (a[i] + b[i]) / 2.0;
32 q = (a[i] + b[i]) / 2.0; 33 if (q > 0) {
33 if (q > 0) 34 if (a[i] > 0) {
34 { 35 d += a[i] * log(a[i] / q);
35 if (a[i] > 0) 36 }
36 d += a[i] * log(a[i] / q); 37 if (b[i] > 0) {
37 if (b[i] > 0) 38 d += b[i] * log(b[i] / q);
38 d += b[i] * log(b[i] / q); 39 }
39 } 40 }
40 } 41 }
41 return d; 42 return d;
42 } 43 }
43 44
44 void cluster_melt(double *h, int m, int n, double *Bsched, int t, int k, int l, int *c) { 45 void cluster_melt(double *h, int m, int n, double *Bsched, int t, int k, int l, int *c) {
45 double lambda, sum, beta, logsumexp, maxlp; 46 double lambda, sum, beta, logsumexp, maxlp;
46 int i, j, a, b, b0, b1, limit, /* B, */ it, maxiter, maxiter0, maxiter1; 47 int i, j, a, b, b0, b1, limit, /* B, */ it, maxiter, maxiter0, maxiter1;
47 double** cl; /* reference histograms for each cluster */ 48 double** cl; /* reference histograms for each cluster */
48 int** nc; /* neighbour counts for each histogram */ 49 int** nc; /* neighbour counts for each histogram */
49 double** lp; /* soft assignment probs for each histogram */ 50 double** lp; /* soft assignment probs for each histogram */
50 int* oldc; /* previous hard assignments (to check convergence) */ 51 int* oldc; /* previous hard assignments (to check convergence) */
51 52
52 /* NB h is passed as a 1d row major array */ 53 /* NB h is passed as a 1d row major array */
53 54
54 /* parameter values */ 55 /* parameter values */
55 lambda = DEFAULT_LAMBDA; 56 lambda = DEFAULT_LAMBDA;
56 if (l > 0) 57 if (l > 0) {
57 limit = l; 58 limit = l;
58 else 59 } else {
59 limit = DEFAULT_LIMIT; /* use default if no valid neighbourhood limit supplied */ 60 limit = DEFAULT_LIMIT; /* use default if no valid neighbourhood limit supplied */
60 // B = 2 * limit + 1; 61 }
61 maxiter0 = 20; /* number of iterations at initial temperature */ 62
62 maxiter1 = 5; /* number of iterations at subsequent temperatures */ 63 maxiter0 = 20; /* number of iterations at initial temperature */
63 64 maxiter1 = 5; /* number of iterations at subsequent temperatures */
64 /* allocate memory */ 65
65 cl = (double**) malloc(k*sizeof(double*)); 66 /* allocate memory */
66 for (i= 0; i < k; i++) 67 cl = (double**) malloc(k*sizeof(double*));
67 cl[i] = (double*) malloc(m*sizeof(double)); 68 for (i= 0; i < k; i++) {
68 69 cl[i] = (double*) malloc(m*sizeof(double));
69 nc = (int**) malloc(n*sizeof(int*)); 70 }
70 for (i= 0; i < n; i++) 71
71 nc[i] = (int*) malloc(k*sizeof(int)); 72 nc = (int**) malloc(n*sizeof(int*));
72 73 for (i= 0; i < n; i++) {
73 lp = (double**) malloc(n*sizeof(double*)); 74 nc[i] = (int*) malloc(k*sizeof(int));
74 for (i= 0; i < n; i++) 75 }
75 lp[i] = (double*) malloc(k*sizeof(double)); 76
76 77 lp = (double**) malloc(n*sizeof(double*));
77 oldc = (int*) malloc(n * sizeof(int)); 78 for (i= 0; i < n; i++) {
78 79 lp[i] = (double*) malloc(k*sizeof(double));
79 /* initialise */ 80 }
80 for (i = 0; i < k; i++) 81
81 { 82 oldc = (int*) malloc(n * sizeof(int));
82 sum = 0; 83
83 for (j = 0; j < m; j++) 84 /* initialise */
84 { 85 for (i = 0; i < k; i++) {
85 cl[i][j] = rand(); /* random initial reference histograms */ 86 sum = 0;
86 sum += cl[i][j] * cl[i][j]; 87 for (j = 0; j < m; j++) {
87 } 88 cl[i][j] = rand(); /* random initial reference histograms */
88 sum = sqrt(sum); 89 sum += cl[i][j] * cl[i][j];
89 for (j = 0; j < m; j++) 90 }
90 { 91 sum = sqrt(sum);
91 cl[i][j] /= sum; /* normalise */ 92 for (j = 0; j < m; j++) {
92 } 93 cl[i][j] /= sum; /* normalise */
93 } 94 }
94 //print_array(cl, k, m); 95 }
95 96
96 for (i = 0; i < n; i++) 97 for (i = 0; i < n; i++) {
97 c[i] = 1; /* initially assign all histograms to cluster 1 */ 98 c[i] = 1; /* initially assign all histograms to cluster 1 */
98 99 }
99 for (a = 0; a < t; a++) 100
100 { 101 for (a = 0; a < t; a++) {
101 beta = Bsched[a]; 102
102 103 beta = Bsched[a];
103 if (a == 0) 104
104 maxiter = maxiter0; 105 if (a == 0) {
105 else 106 maxiter = maxiter0;
106 maxiter = maxiter1; 107 } else {
107 108 maxiter = maxiter1;
108 for (it = 0; it < maxiter; it++) 109 }
109 { 110
110 //if (it == maxiter - 1) 111 for (it = 0; it < maxiter; it++) {
111 // mexPrintf("hasn't converged after %d iterations\n", maxiter); 112
112 113 //if (it == maxiter - 1)
113 for (i = 0; i < n; i++) 114 // mexPrintf("hasn't converged after %d iterations\n", maxiter);
114 { 115
115 /* save current hard assignments */ 116 for (i = 0; i < n; i++) {
116 oldc[i] = c[i]; 117
117 118 /* save current hard assignments */
118 /* calculate soft assignment logprobs for each cluster */ 119 oldc[i] = c[i];
119 sum = 0; 120
120 for (j = 0; j < k; j++) 121 /* calculate soft assignment logprobs for each cluster */
121 { 122 sum = 0;
122 lp[i][ j] = -beta * kldist(cl[j], &h[i*m], m); 123
123 124 for (j = 0; j < k; j++) {
124 /* update matching neighbour counts for this histogram, based on current hard assignments */ 125
125 /* old version: 126 lp[i][ j] = -beta * kldist(cl[j], &h[i*m], m);
126 nc[i][j] = 0; 127
127 if (i >= limit && i <= n - 1 - limit) 128 /* update matching neighbour counts for this histogram, based on current hard assignments */
128 { 129
129 for (b = i - limit; b <= i + limit; b++) 130 b0 = i - limit;
130 { 131 if (b0 < 0) {
131 if (c[b] == j+1) 132 b0 = 0;
132 nc[i][j]++; 133 }
133 } 134 b1 = i + limit;
134 nc[i][j] = B - nc[i][j]; 135 if (b1 >= n) {
135 } 136 b1 = n - 1;
136 */ 137 }
137 b0 = i - limit; 138 nc[i][j] = b1 - b0 + 1; /* = B except at edges */
138 if (b0 < 0) 139 for (b = b0; b <= b1; b++) {
139 b0 = 0; 140 if (c[b] == j+1) {
140 b1 = i + limit; 141 nc[i][j]--;
141 if (b1 >= n) 142 }
142 b1 = n - 1; 143 }
143 nc[i][j] = b1 - b0 + 1; /* = B except at edges */ 144
144 for (b = b0; b <= b1; b++) 145 sum += exp(lp[i][j]);
145 if (c[b] == j+1) 146 }
146 nc[i][j]--; 147
147 148 /* normalise responsibilities and add duration logprior */
148 sum += exp(lp[i][j]); 149 logsumexp = log(sum);
149 } 150 for (j = 0; j < k; j++) {
150 151 lp[i][j] -= logsumexp + lambda * nc[i][j];
151 /* normalise responsibilities and add duration logprior */ 152 }
152 logsumexp = log(sum); 153 }
153 for (j = 0; j < k; j++) 154
154 lp[i][j] -= logsumexp + lambda * nc[i][j]; 155 /* update the assignments now that we know the duration priors
155 } 156 based on the current assignments */
156 //print_array(lp, n, k); 157 for (i = 0; i < n; i++) {
157 /* 158 maxlp = lp[i][0];
158 for (i = 0; i < n; i++) 159 c[i] = 1;
159 { 160 for (j = 1; j < k; j++) {
160 for (j = 0; j < k; j++) 161 if (lp[i][j] > maxlp) {
161 mexPrintf("%d ", nc[i][j]); 162 maxlp = lp[i][j];
162 mexPrintf("\n"); 163 c[i] = j+1;
163 } 164 }
164 */ 165 }
165 166 }
166 167
167 /* update the assignments now that we know the duration priors 168 /* break if assignments haven't changed */
168 based on the current assignments */ 169 i = 0;
169 for (i = 0; i < n; i++) 170 while (i < n && oldc[i] == c[i]) {
170 { 171 i++;
171 maxlp = lp[i][0]; 172 }
172 c[i] = 1; 173 if (i == n) {
173 for (j = 1; j < k; j++) 174 break;
174 if (lp[i][j] > maxlp) 175 }
175 { 176
176 maxlp = lp[i][j]; 177 /* update reference histograms now we know new responsibilities */
177 c[i] = j+1; 178 for (j = 0; j < k; j++) {
178 } 179 for (b = 0; b < m; b++) {
179 } 180 cl[j][b] = 0;
180 181 for (i = 0; i < n; i++) {
181 /* break if assignments haven't changed */ 182 cl[j][b] += exp(lp[i][j]) * h[i*m+b];
182 i = 0; 183 }
183 while (i < n && oldc[i] == c[i]) 184 }
184 i++; 185
185 if (i == n) 186 sum = 0;
186 break; 187 for (i = 0; i < n; i++) {
187 188 sum += exp(lp[i][j]);
188 /* update reference histograms now we know new responsibilities */ 189 }
189 for (j = 0; j < k; j++) 190 for (b = 0; b < m; b++) {
190 { 191 cl[j][b] /= sum; /* normalise */
191 for (b = 0; b < m; b++) 192 }
192 { 193 }
193 cl[j][b] = 0; 194 }
194 for (i = 0; i < n; i++) 195 }
195 { 196
196 cl[j][b] += exp(lp[i][j]) * h[i*m+b]; 197 /* free memory */
197 } 198 for (i = 0; i < k; i++) {
198 } 199 free(cl[i]);
199 200 }
200 sum = 0; 201 free(cl);
201 for (i = 0; i < n; i++) 202 for (i = 0; i < n; i++) {
202 sum += exp(lp[i][j]); 203 free(nc[i]);
203 for (b = 0; b < m; b++) 204 }
204 cl[j][b] /= sum; /* normalise */ 205 free(nc);
205 } 206 for (i = 0; i < n; i++) {
206 207 free(lp[i]);
207 //print_array(cl, k, m); 208 }
208 //mexPrintf("\n\n"); 209 free(lp);
209 } 210 free(oldc);
210 }
211
212 /* free memory */
213 for (i = 0; i < k; i++)
214 free(cl[i]);
215 free(cl);
216 for (i = 0; i < n; i++)
217 free(nc[i]);
218 free(nc);
219 for (i = 0; i < n; i++)
220 free(lp[i]);
221 free(lp);
222 free(oldc);
223 } 211 }
224 212
225 213