comparison hmm/hmm.c @ 483:fdaa63607c15

Untabify, indent, tidy
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 31 May 2019 11:54:32 +0100
parents 7e8d1f26b098
children d48276a3ae24
comparison
equal deleted inserted replaced
482:cbe668c7d724 483:fdaa63607c15
14 14
15 #include <stdio.h> 15 #include <stdio.h>
16 #include <math.h> 16 #include <math.h>
17 #include <stdlib.h> 17 #include <stdlib.h>
18 #include <float.h> 18 #include <float.h>
19 #include <time.h> /* to seed random number generator */ 19 #include <time.h> /* to seed random number generator */
20 20
21 #include <clapack.h> /* LAPACK for matrix inversion */ 21 #include <clapack.h> /* LAPACK for matrix inversion */
22 22
23 #include "maths/nan-inf.h" 23 #include "maths/nan-inf.h"
24 24
25 #ifdef ATLAS_ORDER 25 #ifdef ATLAS_ORDER
26 #define HAVE_ATLAS 1 26 #define HAVE_ATLAS 1
35 #endif 35 #endif
36 36
37 #ifdef _MAC_OS_X 37 #ifdef _MAC_OS_X
38 #include <vecLib/cblas.h> 38 #include <vecLib/cblas.h>
39 #else 39 #else
40 #include <cblas.h> /* BLAS for matrix multiplication */ 40 #include <cblas.h> /* BLAS for matrix multiplication */
41 #endif 41 #endif
42 42
43 #include "hmm.h" 43 #include "hmm.h"
44 44
45 model_t* hmm_init(double** x, int T, int L, int N) 45 model_t* hmm_init(double** x, int T, int L, int N)
46 { 46 {
47 int i, j, d, e, t; 47 int i, j, d, e, t;
48 double s, ss; 48 double s, ss;
49 49
50 model_t* model; 50 model_t* model;
51 model = (model_t*) malloc(sizeof(model_t)); 51 model = (model_t*) malloc(sizeof(model_t));
52 model->N = N; 52 model->N = N;
53 model->L = L; 53 model->L = L;
54 model->p0 = (double*) malloc(N*sizeof(double)); 54 model->p0 = (double*) malloc(N*sizeof(double));
55 model->a = (double**) malloc(N*sizeof(double*)); 55 model->a = (double**) malloc(N*sizeof(double*));
56 model->mu = (double**) malloc(N*sizeof(double*)); 56 model->mu = (double**) malloc(N*sizeof(double*));
57 for (i = 0; i < N; i++) 57 for (i = 0; i < N; i++) {
58 { 58 model->a[i] = (double*) malloc(N*sizeof(double));
59 model->a[i] = (double*) malloc(N*sizeof(double)); 59 model->mu[i] = (double*) malloc(L*sizeof(double));
60 model->mu[i] = (double*) malloc(L*sizeof(double)); 60 }
61 } 61 model->cov = (double**) malloc(L*sizeof(double*));
62 model->cov = (double**) malloc(L*sizeof(double*)); 62 for (i = 0; i < L; i++) {
63 for (i = 0; i < L; i++) 63 model->cov[i] = (double*) malloc(L*sizeof(double));
64 model->cov[i] = (double*) malloc(L*sizeof(double)); 64 }
65 65
66 srand(time(0)); 66 srand(time(0));
67 double* global_mean = (double*) malloc(L*sizeof(double)); 67 double* global_mean = (double*) malloc(L*sizeof(double));
68 68
69 /* find global mean */ 69 /* find global mean */
70 for (d = 0; d < L; d++) 70 for (d = 0; d < L; d++) {
71 { 71 global_mean[d] = 0;
72 global_mean[d] = 0; 72 for (t = 0; t < T; t++) {
73 for (t = 0; t < T; t++) 73 global_mean[d] += x[t][d];
74 global_mean[d] += x[t][d]; 74 }
75 global_mean[d] /= T; 75 global_mean[d] /= T;
76 } 76 }
77 77
78 /* calculate global diagonal covariance */ 78 /* calculate global diagonal covariance */
79 for (d = 0; d < L; d++) 79 for (d = 0; d < L; d++) {
80 { 80 for (e = 0; e < L; e++) {
81 for (e = 0; e < L; e++) 81 model->cov[d][e] = 0;
82 model->cov[d][e] = 0; 82 }
83 for (t = 0; t < T; t++) 83 for (t = 0; t < T; t++) {
84 model->cov[d][d] += (x[t][d] - global_mean[d]) * (x[t][d] - global_mean[d]); 84 model->cov[d][d] +=
85 model->cov[d][d] /= T-1; 85 (x[t][d] - global_mean[d]) * (x[t][d] - global_mean[d]);
86 } 86 }
87 87 model->cov[d][d] /= T-1;
88 /* set all means close to global mean */ 88 }
89 for (i = 0; i < N; i++) 89
90 { 90 /* set all means close to global mean */
91 for (d = 0; d < L; d++) 91 for (i = 0; i < N; i++) {
92 { 92 for (d = 0; d < L; d++) {
93 /* add some random noise related to covariance */ 93 /* add some random noise related to covariance */
94 /* ideally the random number would be Gaussian(0,1), as a hack we make it uniform on [-0.25,0.25] */ 94 /* ideally the random number would be Gaussian(0,1),
95 model->mu[i][d] = global_mean[d] + (0.5 * rand() / (double) RAND_MAX - 0.25) * sqrt(model->cov[d][d]); 95 as a hack we make it uniform on [-0.25,0.25] */
96 } 96 model->mu[i][d] = global_mean[d] +
97 } 97 (0.5 * rand() / (double) RAND_MAX - 0.25)
98 98 * sqrt(model->cov[d][d]);
99 /* random intial and transition probs */ 99 }
100 s = 0; 100 }
101 for (i = 0; i < N; i++) 101
102 { 102 /* random initial and transition probs */
103 model->p0[i] = 1 + rand() / (double) RAND_MAX; 103 s = 0;
104 s += model->p0[i]; 104 for (i = 0; i < N; i++) {
105 ss = 0; 105 model->p0[i] = 1 + rand() / (double) RAND_MAX;
106 for (j = 0; j < N; j++) 106 s += model->p0[i];
107 { 107 ss = 0;
108 model->a[i][j] = 1 + rand() / (double) RAND_MAX; 108 for (j = 0; j < N; j++) {
109 ss += model->a[i][j]; 109 model->a[i][j] = 1 + rand() / (double) RAND_MAX;
110 } 110 ss += model->a[i][j];
111 for (j = 0; j < N; j++) 111 }
112 { 112 for (j = 0; j < N; j++) {
113 model->a[i][j] /= ss; 113 model->a[i][j] /= ss;
114 } 114 }
115 } 115 }
116 for (i = 0; i < N; i++) 116 for (i = 0; i < N; i++) {
117 model->p0[i] /= s; 117 model->p0[i] /= s;
118 118 }
119 free(global_mean); 119
120 120 free(global_mean);
121 return model; 121
122 return model;
122 } 123 }
123 124
124 void hmm_close(model_t* model) 125 void hmm_close(model_t* model)
125 { 126 {
126 int i; 127 int i;
127 128
128 for (i = 0; i < model->N; i++) 129 for (i = 0; i < model->N; i++) {
129 { 130 free(model->a[i]);
130 free(model->a[i]); 131 free(model->mu[i]);
131 free(model->mu[i]); 132 }
132 } 133 free(model->a);
133 free(model->a); 134 free(model->mu);
134 free(model->mu); 135 for (i = 0; i < model->L; i++) {
135 for (i = 0; i < model->L; i++) 136 free(model->cov[i]);
136 free(model->cov[i]); 137 }
137 free(model->cov); 138 free(model->cov);
138 free(model); 139 free(model);
139 } 140 }
140 141
141 void hmm_train(double** x, int T, model_t* model) 142 void hmm_train(double** x, int T, model_t* model)
142 { 143 {
143 int i, t; 144 int i, t;
144 double loglik; /* overall log-likelihood at each iteration */ 145 double loglik; /* overall log-likelihood at each iteration */
145 146
146 int N = model->N; 147 int N = model->N;
147 int L = model->L; 148 int L = model->L;
148 double* p0 = model->p0; 149 double* p0 = model->p0;
149 double** a = model->a; 150 double** a = model->a;
150 double** mu = model->mu; 151 double** mu = model->mu;
151 double** cov = model->cov; 152 double** cov = model->cov;
152 153
153 /* allocate memory */ 154 /* allocate memory */
154 double** gamma = (double**) malloc(T*sizeof(double*)); 155 double** gamma = (double**) malloc(T*sizeof(double*));
155 double*** xi = (double***) malloc(T*sizeof(double**)); 156 double*** xi = (double***) malloc(T*sizeof(double**));
156 for (t = 0; t < T; t++) 157 for (t = 0; t < T; t++) {
157 { 158 gamma[t] = (double*) malloc(N*sizeof(double));
158 gamma[t] = (double*) malloc(N*sizeof(double)); 159 xi[t] = (double**) malloc(N*sizeof(double*));
159 xi[t] = (double**) malloc(N*sizeof(double*)); 160 for (i = 0; i < N; i++) {
160 for (i = 0; i < N; i++) 161 xi[t][i] = (double*) malloc(N*sizeof(double));
161 xi[t][i] = (double*) malloc(N*sizeof(double)); 162 }
162 } 163 }
163 164
164 /* temporary memory */ 165 /* temporary memory */
165 double* gauss_y = (double*) malloc(L*sizeof(double)); 166 double* gauss_y = (double*) malloc(L*sizeof(double));
166 double* gauss_z = (double*) malloc(L*sizeof(double)); 167 double* gauss_z = (double*) malloc(L*sizeof(double));
167 168
168 /* obs probs P(j|{x}) */ 169 /* obs probs P(j|{x}) */
169 double** b = (double**) malloc(T*sizeof(double*)); 170 double** b = (double**) malloc(T*sizeof(double*));
170 for (t = 0; t < T; t++) 171 for (t = 0; t < T; t++) {
171 b[t] = (double*) malloc(N*sizeof(double)); 172 b[t] = (double*) malloc(N*sizeof(double));
172 173 }
173 /* inverse covariance and its determinant */ 174
174 double** icov = (double**) malloc(L*sizeof(double*)); 175 /* inverse covariance and its determinant */
175 for (i = 0; i < L; i++) 176 double** icov = (double**) malloc(L*sizeof(double*));
176 icov[i] = (double*) malloc(L*sizeof(double)); 177 for (i = 0; i < L; i++) {
177 double detcov; 178 icov[i] = (double*) malloc(L*sizeof(double));
178 179 }
179 double thresh = 0.0001; 180 double detcov;
180 int niter = 50; 181
181 int iter = 0; 182 double thresh = 0.0001;
182 double loglik1, loglik2; 183 int niter = 50;
183 int foundnan = 0; 184 int iter = 0;
184 185 double loglik1, loglik2;
185 while (iter < niter && !foundnan && !(iter > 1 && (loglik - loglik1) < thresh * (loglik1 - loglik2))) 186 int foundnan = 0;
186 { 187
187 ++iter; 188 while (iter < niter && !foundnan &&
188 /* 189 !(iter > 1 && (loglik - loglik1) < thresh * (loglik1 - loglik2))) {
189 fprintf(stderr, "calculating obsprobs...\n"); 190
190 fflush(stderr); 191 ++iter;
191 */ 192
192 /* precalculate obs probs */ 193 /* precalculate obs probs */
193 invert(cov, L, icov, &detcov); 194 invert(cov, L, icov, &detcov);
194 195
195 for (t = 0; t < T; t++) 196 for (t = 0; t < T; t++) {
196 { 197 for (i = 0; i < N; i++) {
197 //int allzero = 1; 198 b[t][i] = exp(loggauss(x[t], L, mu[i], icov, detcov, gauss_y, gauss_z));
198 for (i = 0; i < N; i++) 199 }
199 { 200 }
200 b[t][i] = exp(loggauss(x[t], L, mu[i], icov, detcov, gauss_y, gauss_z)); 201 forward_backwards(xi, gamma, &loglik, &loglik1, &loglik2,
201 202 iter, N, T, p0, a, b);
202 //if (b[t][i] != 0) 203 if (ISNAN(loglik)) {
203 // allzero = 0; 204 foundnan = 1;
204 } 205 continue;
205 /* 206 }
206 if (allzero) 207
207 { 208 baum_welch(p0, a, mu, cov, N, T, L, x, xi, gamma);
208 printf("all the b[t][i] were zero for t = %d, correcting...\n", t); 209 }
209 for (i = 0; i < N; i++) 210
210 { 211 /* deallocate memory */
211 b[t][i] = 0.00001; 212 for (t = 0; t < T; t++) {
212 } 213 free(gamma[t]);
213 } 214 free(b[t]);
214 */ 215 for (i = 0; i < N; i++) {
215 } 216 free(xi[t][i]);
216 /* 217 }
217 fprintf(stderr, "forwards-backwards...\n"); 218 free(xi[t]);
218 fflush(stderr); 219 }
219 */ 220 free(gamma);
220 forward_backwards(xi, gamma, &loglik, &loglik1, &loglik2, iter, N, T, p0, a, b); 221 free(xi);
221 /* 222 free(b);
222 fprintf(stderr, "iteration %d: loglik = %f\n", iter, loglik); 223
223 fprintf(stderr, "re-estimation...\n"); 224 for (i = 0; i < L; i++) {
224 fflush(stderr); 225 free(icov[i]);
225 */ 226 }
226 if (ISNAN(loglik)) { 227 free(icov);
227 foundnan = 1; 228
228 continue; 229 free(gauss_y);
229 } 230 free(gauss_z);
230 231 }
231 baum_welch(p0, a, mu, cov, N, T, L, x, xi, gamma); 232
232 233 void baum_welch(double* p0, double** a, double** mu, double** cov,
233 /* 234 int N, int T, int L, double** x, double*** xi, double** gamma)
234 printf("a:\n"); 235 {
235 for (i = 0; i < model->N; i++) 236 int i, j, t;
236 { 237
237 for (j = 0; j < model->N; j++) 238 double* sum_gamma = (double*) malloc(N*sizeof(double));
238 printf("%f ", model->a[i][j]); 239
239 printf("\n"); 240 /* temporary memory */
240 } 241 double* u = (double*) malloc(L*L*sizeof(double));
241 printf("\n\n"); 242 double* yy = (double*) malloc(T*L*sizeof(double));
242 */ 243 double* yy2 = (double*) malloc(T*L*sizeof(double));
243 //hmm_print(model); 244
244 } 245 /* re-estimate transition probs */
245 246 for (i = 0; i < N; i++) {
246 /* deallocate memory */ 247 sum_gamma[i] = 0;
247 for (t = 0; t < T; t++) 248 for (t = 0; t < T-1; t++) {
248 { 249 sum_gamma[i] += gamma[t][i];
249 free(gamma[t]); 250 }
250 free(b[t]); 251 }
251 for (i = 0; i < N; i++) 252
252 free(xi[t][i]); 253 for (i = 0; i < N; i++) {
253 free(xi[t]); 254 for (j = 0; j < N; j++) {
254 } 255 a[i][j] = 0;
255 free(gamma); 256 if (sum_gamma[i] == 0.) {
256 free(xi); 257 continue;
257 free(b); 258 }
258 259 for (t = 0; t < T-1; t++) {
259 for (i = 0; i < L; i++) 260 a[i][j] += xi[t][i][j];
260 free(icov[i]); 261 }
261 free(icov); 262 a[i][j] /= sum_gamma[i];
262 263 }
263 free(gauss_y); 264 }
264 free(gauss_z); 265
265 } 266 /* NB: now we need to sum gamma over all t */
266 267 for (i = 0; i < N; i++) {
267 void baum_welch(double* p0, double** a, double** mu, double** cov, int N, int T, int L, double** x, double*** xi, double** gamma) 268 sum_gamma[i] += gamma[T-1][i];
268 { 269 }
269 int i, j, t; 270
270 271 /* re-estimate initial probs */
271 double* sum_gamma = (double*) malloc(N*sizeof(double)); 272 for (i = 0; i < N; i++) {
272 273 p0[i] = gamma[0][i];
273 /* temporary memory */ 274 }
274 double* u = (double*) malloc(L*L*sizeof(double)); 275
275 double* yy = (double*) malloc(T*L*sizeof(double)); 276 /* re-estimate covariance */
276 double* yy2 = (double*) malloc(T*L*sizeof(double)); 277 int d, e;
277 278 double sum_sum_gamma = 0;
278 /* re-estimate transition probs */ 279 for (i = 0; i < N; i++) {
279 for (i = 0; i < N; i++) 280 sum_sum_gamma += sum_gamma[i];
280 { 281 }
281 sum_gamma[i] = 0; 282
282 for (t = 0; t < T-1; t++) 283 /* using BLAS */
283 sum_gamma[i] += gamma[t][i]; 284 for (d = 0; d < L; d++) {
284 } 285 for (e = 0; e < L; e++) {
285 286 cov[d][e] = 0;
286 for (i = 0; i < N; i++) 287 }
287 { 288 }
288 if (sum_gamma[i] == 0) 289
289 { 290 for (j = 0; j < N; j++) {
290 /* fprintf(stderr, "sum_gamma[%d] was zero...\n", i); */ 291
291 } 292 for (d = 0; d < L; d++) {
292 //double s = 0; 293 for (t = 0; t < T; t++) {
293 for (j = 0; j < N; j++) 294 yy[d*T+t] = x[t][d] - mu[j][d];
294 { 295 yy2[d*T+t] = gamma[t][j] * (x[t][d] - mu[j][d]);
295 a[i][j] = 0; 296 }
296 if (sum_gamma[i] == 0.) continue; 297 }
297 for (t = 0; t < T-1; t++) 298
298 a[i][j] += xi[t][i][j]; 299 cblas_dgemm(CblasColMajor, CblasTrans, CblasNoTrans,
299 //s += a[i][j]; 300 L, L, T, 1.0, yy, T, yy2, T, 0, u, L);
300 a[i][j] /= sum_gamma[i]; 301
301 } 302 for (e = 0; e < L; e++) {
302 /* 303 for (d = 0; d < L; d++) {
303 for (j = 0; j < N; j++) 304 cov[d][e] += u[e*L+d];
304 { 305 }
305 a[i][j] /= s; 306 }
306 } 307 }
307 */ 308
308 } 309 for (d = 0; d < L; d++) {
309 310 for (e = 0; e < L; e++) {
310 /* NB: now we need to sum gamma over all t */ 311 cov[d][e] /= T; /* sum_sum_gamma; */
311 for (i = 0; i < N; i++) 312 }
312 sum_gamma[i] += gamma[T-1][i]; 313 }
313 314
314 /* re-estimate initial probs */ 315 //printf("sum_sum_gamma = %f\n", sum_sum_gamma); /* fine, = T IS THIS ALWAYS TRUE with pooled cov?? */
315 for (i = 0; i < N; i++) 316
316 p0[i] = gamma[0][i]; 317 /* re-estimate means */
317 318 for (j = 0; j < N; j++) {
318 /* re-estimate covariance */ 319 for (d = 0; d < L; d++) {
319 int d, e; 320 mu[j][d] = 0;
320 double sum_sum_gamma = 0; 321 for (t = 0; t < T; t++)
321 for (i = 0; i < N; i++) 322 mu[j][d] += gamma[t][j] * x[t][d];
322 sum_sum_gamma += sum_gamma[i]; 323 mu[j][d] /= sum_gamma[j];
323 324 }
324 /* 325 }
325 for (d = 0; d < L; d++) 326
326 { 327 /* deallocate memory */
327 for (e = d; e < L; e++) 328 free(sum_gamma);
328 { 329 free(yy);
329 cov[d][e] = 0; 330 free(yy2);
330 for (t = 0; t < T; t++) 331 free(u);
331 for (j = 0; j < N; j++) 332 }
332 cov[d][e] += gamma[t][j] * (x[t][d] - mu[j][d]) * (x[t][e] - mu[j][e]); 333
333 334 void forward_backwards(double*** xi, double** gamma,
334 cov[d][e] /= sum_sum_gamma; 335 double* loglik, double* loglik1, double* loglik2,
335 336 int iter, int N, int T,
336 if (ISNAN(cov[d][e])) 337 double* p0, double** a, double** b)
337 { 338 {
338 printf("cov[%d][%d] was nan\n", d, e); 339 /* forwards-backwards with scaling */
339 for (j = 0; j < N; j++) 340 int i, j, t;
340 for (i = 0; i < L; i++) 341
341 if (ISNAN(mu[j][i])) 342 double** alpha = (double**) malloc(T*sizeof(double*));
342 printf("mu[%d][%d] was nan\n", j, i); 343 double** beta = (double**) malloc(T*sizeof(double*));
343 for (t = 0; t < T; t++) 344 for (t = 0; t < T; t++) {
344 for (j = 0; j < N; j++) 345 alpha[t] = (double*) malloc(N*sizeof(double));
345 if (ISNAN(gamma[t][j])) 346 beta[t] = (double*) malloc(N*sizeof(double));
346 printf("gamma[%d][%d] was nan\n", t, j); 347 }
347 exit(-1); 348
348 } 349 /* scaling coefficients */
349 } 350 double* c = (double*) malloc(T*sizeof(double));
350 } 351
351 for (d = 0; d < L; d++) 352 /* calculate forward probs and scale coefficients */
352 for (e = 0; e < d; e++) 353 c[0] = 0;
353 cov[d][e] = cov[e][d]; 354 for (i = 0; i < N; i++) {
354 */ 355 alpha[0][i] = p0[i] * b[0][i];
355 356 c[0] += alpha[0][i];
356 /* using BLAS */ 357 }
357 for (d = 0; d < L; d++) 358 c[0] = 1 / c[0];
358 for (e = 0; e < L; e++) 359 for (i = 0; i < N; i++) {
359 cov[d][e] = 0; 360 alpha[0][i] *= c[0];
360 361 }
361 for (j = 0; j < N; j++) 362
362 { 363 *loglik1 = *loglik;
363 for (d = 0; d < L; d++) 364 *loglik = -log(c[0]);
364 for (t = 0; t < T; t++) 365 if (iter == 2) {
365 { 366 *loglik2 = *loglik;
366 yy[d*T+t] = x[t][d] - mu[j][d]; 367 }
367 yy2[d*T+t] = gamma[t][j] * (x[t][d] - mu[j][d]); 368
368 } 369 for (t = 1; t < T; t++) {
369 370
370 cblas_dgemm(CblasColMajor, CblasTrans, CblasNoTrans, L, L, T, 1.0, yy, T, yy2, T, 0, u, L); 371 c[t] = 0;
371 372
372 for (e = 0; e < L; e++) 373 for (j = 0; j < N; j++) {
373 for (d = 0; d < L; d++) 374 alpha[t][j] = 0;
374 cov[d][e] += u[e*L+d]; 375 for (i = 0; i < N; i++) {
375 } 376 alpha[t][j] += alpha[t-1][i] * a[i][j];
376 377 }
377 for (d = 0; d < L; d++) 378 alpha[t][j] *= b[t][j];
378 for (e = 0; e < L; e++) 379
379 cov[d][e] /= T; /* sum_sum_gamma; */ 380 c[t] += alpha[t][j];
380 381 }
381 //printf("sum_sum_gamma = %f\n", sum_sum_gamma); /* fine, = T IS THIS ALWAYS TRUE with pooled cov?? */ 382
382 383 c[t] = 1 / c[t];
383 /* re-estimate means */ 384 for (j = 0; j < N; j++) {
384 for (j = 0; j < N; j++) 385 alpha[t][j] *= c[t];
385 { 386 }
386 for (d = 0; d < L; d++) 387
387 { 388 *loglik -= log(c[t]);
388 mu[j][d] = 0; 389 }
389 for (t = 0; t < T; t++) 390
390 mu[j][d] += gamma[t][j] * x[t][d]; 391 /* calculate backwards probs using same coefficients */
391 mu[j][d] /= sum_gamma[j]; 392 for (i = 0; i < N; i++) {
392 } 393 beta[T-1][i] = 1;
393 } 394 }
394 395 t = T - 1;
395 /* deallocate memory */ 396
396 free(sum_gamma); 397 while (1) {
397 free(yy); 398 for (i = 0; i < N; i++) {
398 free(yy2); 399 beta[t][i] *= c[t];
399 free(u); 400 }
400 } 401
401 402 if (t == 0) {
402 void forward_backwards(double*** xi, double** gamma, double* loglik, double* loglik1, double* loglik2, int iter, int N, int T, double* p0, double** a, double** b) 403 break;
403 { 404 }
404 /* forwards-backwards with scaling */ 405
405 int i, j, t; 406 for (i = 0; i < N; i++) {
406 407 beta[t-1][i] = 0;
407 double** alpha = (double**) malloc(T*sizeof(double*)); 408 for (j = 0; j < N; j++) {
408 double** beta = (double**) malloc(T*sizeof(double*)); 409 beta[t-1][i] += a[i][j] * b[t][j] * beta[t][j];
409 for (t = 0; t < T; t++) 410 }
410 { 411 }
411 alpha[t] = (double*) malloc(N*sizeof(double)); 412
412 beta[t] = (double*) malloc(N*sizeof(double)); 413 t--;
413 } 414 }
414 415
415 /* scaling coefficients */ 416 /* calculate posterior probs */
416 double* c = (double*) malloc(T*sizeof(double)); 417 double tot;
417 418 for (t = 0; t < T; t++) {
418 /* calculate forward probs and scale coefficients */ 419 tot = 0;
419 c[0] = 0; 420 for (i = 0; i < N; i++) {
420 for (i = 0; i < N; i++) 421 gamma[t][i] = alpha[t][i] * beta[t][i];
421 { 422 tot += gamma[t][i];
422 alpha[0][i] = p0[i] * b[0][i]; 423 }
423 c[0] += alpha[0][i]; 424 for (i = 0; i < N; i++) {
424 425 gamma[t][i] /= tot;
425 //printf("p0[%d] = %f, b[0][%d] = %f\n", i, p0[i], i, b[0][i]); 426 }
426 } 427 }
427 c[0] = 1 / c[0]; 428
428 for (i = 0; i < N; i++) 429 for (t = 0; t < T-1; t++) {
429 { 430 tot = 0;
430 alpha[0][i] *= c[0]; 431 for (i = 0; i < N; i++) {
431 432 for (j = 0; j < N; j++) {
432 //printf("alpha[0][%d] = %f\n", i, alpha[0][i]); /* OK agrees with Matlab */ 433 xi[t][i][j] = alpha[t][i] * a[i][j] * b[t+1][j] * beta[t+1][j];
433 } 434 tot += xi[t][i][j];
434 435 }
435 *loglik1 = *loglik; 436 }
436 *loglik = -log(c[0]); 437 for (i = 0; i < N; i++) {
437 if (iter == 2) 438 for (j = 0; j < N; j++) {
438 *loglik2 = *loglik; 439 xi[t][i][j] /= tot;
439 440 }
440 for (t = 1; t < T; t++) 441 }
441 { 442 }
442 c[t] = 0; 443
443 for (j = 0; j < N; j++) 444 for (t = 0; t < T; t++) {
444 { 445 free(alpha[t]);
445 alpha[t][j] = 0; 446 free(beta[t]);
446 for (i = 0; i < N; i++) 447 }
447 alpha[t][j] += alpha[t-1][i] * a[i][j]; 448 free(alpha);
448 alpha[t][j] *= b[t][j]; 449 free(beta);
449 450 free(c);
450 c[t] += alpha[t][j];
451 }
452
453 /*
454 if (c[t] == 0)
455 {
456 printf("c[%d] = 0, going to blow up so exiting\n", t);
457 for (i = 0; i < N; i++)
458 if (b[t][i] == 0)
459 fprintf(stderr, "b[%d][%d] was zero\n", t, i);
460 fprintf(stderr, "x[t] was \n");
461 for (i = 0; i < L; i++)
462 fprintf(stderr, "%f ", x[t][i]);
463 fprintf(stderr, "\n\n");
464 exit(-1);
465 }
466 */
467
468 c[t] = 1 / c[t];
469 for (j = 0; j < N; j++)
470 alpha[t][j] *= c[t];
471
472 //printf("c[%d] = %e\n", t, c[t]);
473
474 *loglik -= log(c[t]);
475 }
476
477 /* calculate backwards probs using same coefficients */
478 for (i = 0; i < N; i++)
479 beta[T-1][i] = 1;
480 t = T - 1;
481 while (1)
482 {
483 for (i = 0; i < N; i++)
484 beta[t][i] *= c[t];
485
486 if (t == 0)
487 break;
488
489 for (i = 0; i < N; i++)
490 {
491 beta[t-1][i] = 0;
492 for (j = 0; j < N; j++)
493 beta[t-1][i] += a[i][j] * b[t][j] * beta[t][j];
494 }
495
496 t--;
497 }
498
499 /*
500 printf("alpha:\n");
501 for (t = 0; t < T; t++)
502 {
503 for (i = 0; i < N; i++)
504 printf("%4.4e\t\t", alpha[t][i]);
505 printf("\n");
506 }
507 printf("\n\n");printf("beta:\n");
508 for (t = 0; t < T; t++)
509 {
510 for (i = 0; i < N; i++)
511 printf("%4.4e\t\t", beta[t][i]);
512 printf("\n");
513 }
514 printf("\n\n");
515 */
516
517 /* calculate posterior probs */
518 double tot;
519 for (t = 0; t < T; t++)
520 {
521 tot = 0;
522 for (i = 0; i < N; i++)
523 {
524 gamma[t][i] = alpha[t][i] * beta[t][i];
525 tot += gamma[t][i];
526 }
527 for (i = 0; i < N; i++)
528 {
529 gamma[t][i] /= tot;
530
531 //printf("gamma[%d][%d] = %f\n", t, i, gamma[t][i]);
532 }
533 }
534
535 for (t = 0; t < T-1; t++)
536 {
537 tot = 0;
538 for (i = 0; i < N; i++)
539 {
540 for (j = 0; j < N; j++)
541 {
542 xi[t][i][j] = alpha[t][i] * a[i][j] * b[t+1][j] * beta[t+1][j];
543 tot += xi[t][i][j];
544 }
545 }
546 for (i = 0; i < N; i++)
547 for (j = 0; j < N; j++)
548 xi[t][i][j] /= tot;
549 }
550
551 /*
552 // CHECK - fine
553 // gamma[t][i] = \sum_j{xi[t][i][j]}
554 tot = 0;
555 for (j = 0; j < N; j++)
556 tot += xi[3][1][j];
557 printf("gamma[3][1] = %f, sum_j(xi[3][1][j]) = %f\n", gamma[3][1], tot);
558 */
559
560 for (t = 0; t < T; t++)
561 {
562 free(alpha[t]);
563 free(beta[t]);
564 }
565 free(alpha);
566 free(beta);
567 free(c);
568 } 451 }
569 452
570 void viterbi_decode(double** x, int T, model_t* model, int* q) 453 void viterbi_decode(double** x, int T, model_t* model, int* q)
571 { 454 {
572 int i, j, t; 455 int i, j, t;
573 double max; 456 double max;
574 int havemax; 457 int havemax;
575 458
576 int N = model->N; 459 int N = model->N;
577 int L = model->L; 460 int L = model->L;
578 double* p0 = model->p0; 461 double* p0 = model->p0;
579 double** a = model->a; 462 double** a = model->a;
580 double** mu = model->mu; 463 double** mu = model->mu;
581 double** cov = model->cov; 464 double** cov = model->cov;
582 465
583 /* inverse covariance and its determinant */ 466 /* inverse covariance and its determinant */
584 double** icov = (double**) malloc(L*sizeof(double*)); 467 double** icov = (double**) malloc(L*sizeof(double*));
585 for (i = 0; i < L; i++) 468 for (i = 0; i < L; i++) {
586 icov[i] = (double*) malloc(L*sizeof(double)); 469 icov[i] = (double*) malloc(L*sizeof(double));
587 double detcov; 470 }
588 471 double detcov;
589 double** logb = (double**) malloc(T*sizeof(double*)); 472
590 double** phi = (double**) malloc(T*sizeof(double*)); 473 double** logb = (double**) malloc(T*sizeof(double*));
591 int** psi = (int**) malloc(T*sizeof(int*)); 474 double** phi = (double**) malloc(T*sizeof(double*));
592 for (t = 0; t < T; t++) 475 int** psi = (int**) malloc(T*sizeof(int*));
593 { 476
594 logb[t] = (double*) malloc(N*sizeof(double)); 477 for (t = 0; t < T; t++) {
595 phi[t] = (double*) malloc(N*sizeof(double)); 478 logb[t] = (double*) malloc(N*sizeof(double));
596 psi[t] = (int*) malloc(N*sizeof(int)); 479 phi[t] = (double*) malloc(N*sizeof(double));
597 } 480 psi[t] = (int*) malloc(N*sizeof(int));
598 481 }
599 /* temporary memory */ 482
600 double* gauss_y = (double*) malloc(L*sizeof(double)); 483 /* temporary memory */
601 double* gauss_z = (double*) malloc(L*sizeof(double)); 484 double* gauss_y = (double*) malloc(L*sizeof(double));
602 485 double* gauss_z = (double*) malloc(L*sizeof(double));
603 /* calculate observation logprobs */ 486
604 invert(cov, L, icov, &detcov); 487 /* calculate observation logprobs */
605 for (t = 0; t < T; t++) 488 invert(cov, L, icov, &detcov);
606 for (i = 0; i < N; i++) 489 for (t = 0; t < T; t++) {
607 logb[t][i] = loggauss(x[t], L, mu[i], icov, detcov, gauss_y, gauss_z); 490 for (i = 0; i < N; i++) {
608 491 logb[t][i] = loggauss
609 /* initialise */ 492 (x[t], L, mu[i], icov, detcov, gauss_y, gauss_z);
610 for (i = 0; i < N; i++) 493 }
611 { 494 }
612 phi[0][i] = log(p0[i]) + logb[0][i]; 495
613 psi[0][i] = 0; 496 /* initialise */
614 } 497 for (i = 0; i < N; i++) {
615 498 phi[0][i] = log(p0[i]) + logb[0][i];
616 for (t = 1; t < T; t++) 499 psi[0][i] = 0;
617 { 500 }
618 for (j = 0; j < N; j++) 501
619 { 502 for (t = 1; t < T; t++) {
620 max = -1000000; 503 for (j = 0; j < N; j++) {
621 havemax = 0; 504 max = -1000000;
622 505 havemax = 0;
623 psi[t][j] = 0; 506
624 for (i = 0; i < N; i++) 507 psi[t][j] = 0;
625 { 508 for (i = 0; i < N; i++) {
626 if (phi[t-1][i] + log(a[i][j]) > max || !havemax) 509 if (phi[t-1][i] + log(a[i][j]) > max || !havemax) {
627 { 510 max = phi[t-1][i] + log(a[i][j]);
628 max = phi[t-1][i] + log(a[i][j]); 511 phi[t][j] = max + logb[t][j];
629 phi[t][j] = max + logb[t][j]; 512 psi[t][j] = i;
630 psi[t][j] = i; 513 havemax = 1;
631 havemax = 1; 514 }
632 } 515 }
633 } 516 }
634 } 517 }
635 } 518
636 519 /* find maximising state at time T-1 */
637 /* find maximising state at time T-1 */ 520 max = phi[T-1][0];
638 max = phi[T-1][0]; 521 q[T-1] = 0;
639 q[T-1] = 0; 522 for (i = 1; i < N; i++) {
640 for (i = 1; i < N; i++) 523 if (phi[T-1][i] > max) {
641 { 524 max = phi[T-1][i];
642 if (phi[T-1][i] > max) 525 q[T-1] = i;
643 { 526 }
644 max = phi[T-1][i]; 527 }
645 q[T-1] = i; 528
646 } 529 /* track back */
647 } 530 t = T - 2;
648 531 while (t >= 0) {
649 532 q[t] = psi[t+1][q[t+1]];
650 /* track back */ 533 t--;
651 t = T - 2; 534 }
652 while (t >= 0) 535
653 { 536 /* de-allocate memory */
654 q[t] = psi[t+1][q[t+1]]; 537 for (i = 0; i < L; i++) {
655 t--; 538 free(icov[i]);
656 } 539 }
657 540 free(icov);
658 /* de-allocate memory */ 541 for (t = 0; t < T; t++) {
659 for (i = 0; i < L; i++) 542 free(logb[t]);
660 free(icov[i]); 543 free(phi[t]);
661 free(icov); 544 free(psi[t]);
662 for (t = 0; t < T; t++) 545 }
663 { 546 free(logb);
664 free(logb[t]); 547 free(phi);
665 free(phi[t]); 548 free(psi);
666 free(psi[t]); 549
667 } 550 free(gauss_y);
668 free(logb); 551 free(gauss_z);
669 free(phi);
670 free(psi);
671
672 free(gauss_y);
673 free(gauss_z);
674 } 552 }
675 553
676 /* invert matrix and calculate determinant using LAPACK */ 554 /* invert matrix and calculate determinant using LAPACK */
677 void invert(double** cov, int L, double** icov, double* detcov) 555 void invert(double** cov, int L, double** icov, double* detcov)
678 { 556 {
679 /* copy square matrix into a vector in column-major order */ 557 /* copy square matrix into a vector in column-major order */
680 double* a = (double*) malloc(L*L*sizeof(double)); 558 double* a = (double*) malloc(L*L*sizeof(double));
681 int i, j; 559 int i, j;
682 for(j=0; j < L; j++) 560 for (j=0; j < L; j++) {
683 for (i=0; i < L; i++) 561 for (i=0; i < L; i++) {
684 a[j*L+i] = cov[i][j]; 562 a[j*L+i] = cov[i][j];
685 563 }
686 int M = (int) L; 564 }
687 int* ipiv = (int *) malloc(L*L*sizeof(int)); 565
688 int ret; 566 int M = (int) L;
689 567 int* ipiv = (int *) malloc(L*L*sizeof(int));
690 /* LU decomposition */ 568 int ret;
691 ret = dgetrf_(&M, &M, a, &M, ipiv, &ret); /* ret should be zero, negative if cov is singular */ 569
692 if (ret < 0) 570 /* LU decomposition */
693 { 571 ret = dgetrf_(&M, &M, a, &M, ipiv, &ret); /* ret should be zero, negative if cov is singular */
694 fprintf(stderr, "Covariance matrix was singular, couldn't invert\n"); 572 if (ret < 0) {
695 exit(-1); 573 fprintf(stderr, "Covariance matrix was singular, couldn't invert\n");
696 } 574 exit(-1);
697 575 }
698 /* find determinant */ 576
699 double det = 1; 577 /* find determinant */
700 for(i = 0; i < L; i++) 578 double det = 1;
701 det *= a[i*L+i]; 579 for (i = 0; i < L; i++) {
702 // TODO: get this to work!!! If detcov < 0 then cov is bad anyway... 580 det *= a[i*L+i];
703 /* 581 }
704 int sign = 1; 582
705 for (i = 0; i < L; i++) 583 // TODO: get this to work!!! If detcov < 0 then cov is bad anyway...
706 if (ipiv[i] != i) 584 if (det < 0) {
707 sign = -sign; 585 det = -det;
708 det *= sign; 586 }
709 */ 587 *detcov = det;
710 if (det < 0) 588
711 det = -det; 589 /* allocate required working storage */
712 *detcov = det;
713
714 /* allocate required working storage */
715 #ifndef HAVE_ATLAS 590 #ifndef HAVE_ATLAS
716 int lwork = -1; 591 int lwork = -1;
717 double lwbest = 0.0; 592 double lwbest = 0.0;
718 dgetri_(&M, a, &M, ipiv, &lwbest, &lwork, &ret); 593 dgetri_(&M, a, &M, ipiv, &lwbest, &lwork, &ret);
719 lwork = (int) lwbest; 594 lwork = (int) lwbest;
720 double* work = (double*) malloc(lwork*sizeof(double)); 595 double* work = (double*) malloc(lwork*sizeof(double));
721 #endif 596 #endif
722 597
723 /* find inverse */ 598 /* find inverse */
724 dgetri_(&M, a, &M, ipiv, work, &lwork, &ret); 599 dgetri_(&M, a, &M, ipiv, work, &lwork, &ret);
725 600
726 for(j=0; j < L; j++) 601 for (j=0; j < L; j++) {
727 for (i=0; i < L; i++) 602 for (i=0; i < L; i++) {
728 icov[i][j] = a[j*L+i]; 603 icov[i][j] = a[j*L+i];
604 }
605 }
729 606
730 #ifndef HAVE_ATLAS 607 #ifndef HAVE_ATLAS
731 free(work); 608 free(work);
732 #endif 609 #endif
733 free(a); 610 free(a);
734 } 611 }
735 612
736 /* probability of multivariate Gaussian given mean, inverse and determinant of covariance */ 613 /* probability of multivariate Gaussian given mean, inverse and determinant of covariance */
737 double gauss(double* x, int L, double* mu, double** icov, double detcov, double* y, double* z) 614 double gauss(double* x, int L, double* mu, double** icov, double detcov, double* y, double* z)
738 { 615 {
739 int i; 616 int i;
740 double s = 0; 617 double s = 0;
741 for (i = 0; i < L; i++) 618
742 y[i] = x[i] - mu[i]; 619 for (i = 0; i < L; i++) {
743 for (i = 0; i < L; i++) 620 y[i] = x[i] - mu[i];
744 { 621 }
745 //z[i] = 0; 622
746 //for (j = 0; j < L; j++) 623 for (i = 0; i < L; i++) {
747 // z[i] += icov[i][j] * y[j]; 624 z[i] = cblas_ddot(L, &icov[i][0], 1, y, 1);
748 z[i] = cblas_ddot(L, &icov[i][0], 1, y, 1); 625 }
749 } 626
750 s = cblas_ddot(L, z, 1, y, 1); 627 s = cblas_ddot(L, z, 1, y, 1);
751 //for (i = 0; i < L; i++) 628
752 // s += z[i] * y[i]; 629 return exp(-s/2.0) / (pow(2*PI, L/2.0) * sqrt(detcov));
753
754 return exp(-s/2.0) / (pow(2*PI, L/2.0) * sqrt(detcov));
755 } 630 }
756 631
757 /* log probability of multivariate Gaussian given mean, inverse and determinant of covariance */ 632 /* log probability of multivariate Gaussian given mean, inverse and determinant of covariance */
758 double loggauss(double* x, int L, double* mu, double** icov, double detcov, double* y, double* z) 633 double loggauss(double* x, int L, double* mu, double** icov, double detcov, double* y, double* z)
759 { 634 {
760 int i; 635 int i;
761 double s = 0; 636 double s = 0;
762 double ret; 637 double ret;
763 for (i = 0; i < L; i++) 638
764 y[i] = x[i] - mu[i]; 639 for (i = 0; i < L; i++) {
765 for (i = 0; i < L; i++) 640 y[i] = x[i] - mu[i];
766 { 641 }
767 //z[i] = 0; 642
768 //for (j = 0; j < L; j++) 643 for (i = 0; i < L; i++) {
769 // z[i] += icov[i][j] * y[j]; 644 z[i] = cblas_ddot(L, &icov[i][0], 1, y, 1);
770 z[i] = cblas_ddot(L, &icov[i][0], 1, y, 1); 645 }
771 } 646
772 s = cblas_ddot(L, z, 1, y, 1); 647 s = cblas_ddot(L, z, 1, y, 1);
773 //for (i = 0; i < L; i++) 648
774 // s += z[i] * y[i]; 649 ret = -0.5 * (s + L * log(2*PI) + log(detcov));
775 650
776 ret = -0.5 * (s + L * log(2*PI) + log(detcov)); 651 return ret;
777
778 /*
779 // TEST
780 if (ISINF(ret) > 0)
781 printf("loggauss returning infinity\n");
782 if (ISINF(ret) < 0)
783 printf("loggauss returning -infinity\n");
784 if (ISNAN(ret))
785 printf("loggauss returning nan\n");
786 */
787
788 return ret;
789 } 652 }
790 653
791 void hmm_print(model_t* model) 654 void hmm_print(model_t* model)
792 { 655 {
793 int i, j; 656 int i, j;
794 printf("p0:\n"); 657 printf("p0:\n");
795 for (i = 0; i < model->N; i++) 658 for (i = 0; i < model->N; i++) {
796 printf("%f ", model->p0[i]); 659 printf("%f ", model->p0[i]);
797 printf("\n\n"); 660 }
798 printf("a:\n"); 661 printf("\n\n");
799 for (i = 0; i < model->N; i++) 662 printf("a:\n");
800 { 663 for (i = 0; i < model->N; i++) {
801 for (j = 0; j < model->N; j++) 664 for (j = 0; j < model->N; j++) {
802 printf("%f ", model->a[i][j]); 665 printf("%f ", model->a[i][j]);
803 printf("\n"); 666 }
804 } 667 printf("\n");
805 printf("\n\n"); 668 }
806 printf("mu:\n"); 669 printf("\n\n");
807 for (i = 0; i < model->N; i++) 670 printf("mu:\n");
808 { 671 for (i = 0; i < model->N; i++) {
809 for (j = 0; j < model->L; j++) 672 for (j = 0; j < model->L; j++) {
810 printf("%f ", model->mu[i][j]); 673 printf("%f ", model->mu[i][j]);
811 printf("\n"); 674 }
812 } 675 printf("\n");
813 printf("\n\n"); 676 }
814 printf("cov:\n"); 677 printf("\n\n");
815 for (i = 0; i < model->L; i++) 678 printf("cov:\n");
816 { 679 for (i = 0; i < model->L; i++) {
817 for (j = 0; j < model->L; j++) 680 for (j = 0; j < model->L; j++) {
818 printf("%f ", model->cov[i][j]); 681 printf("%f ", model->cov[i][j]);
819 printf("\n"); 682 }
820 } 683 printf("\n");
821 printf("\n\n"); 684 }
822 } 685 printf("\n\n");
823 686 }
824 687
688