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