Mercurial > hg > qm-dsp
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 |