Bug Summary

File:modules/clustergen/simple_mlpg.cc
Location:line 982, column 9
Description:Value stored to 'like' is never read

Annotated Source Code

1/* --------------------------------------------------------------- */
2/* The HMM-Based Speech Synthesis System (HTS): version 1.1.1 */
3/* HTS Working Group */
4/* */
5/* Department of Computer Science */
6/* Nagoya Institute of Technology */
7/* and */
8/* Interdisciplinary Graduate School of Science and Engineering */
9/* Tokyo Institute of Technology */
10/* Copyright (c) 2001-2003 */
11/* All Rights Reserved. */
12/* */
13/* Permission is hereby granted, free of charge, to use and */
14/* distribute this software and its documentation without */
15/* restriction, including without limitation the rights to use, */
16/* copy, modify, merge, publish, distribute, sublicense, and/or */
17/* sell copies of this work, and to permit persons to whom this */
18/* work is furnished to do so, subject to the following conditions: */
19/* */
20/* 1. The code must retain the above copyright notice, this list */
21/* of conditions and the following disclaimer. */
22/* */
23/* 2. Any modifications must be clearly marked as such. */
24/* */
25/* NAGOYA INSTITUTE OF TECHNOLOGY, TOKYO INSITITUTE OF TECHNOLOGY, */
26/* HTS WORKING GROUP, AND THE CONTRIBUTORS TO THIS WORK DISCLAIM */
27/* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL */
28/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
29/* SHALL NAGOYA INSTITUTE OF TECHNOLOGY, TOKYO INSITITUTE OF */
30/* TECHNOLOGY, HTS WORKING GROUP, NOR THE CONTRIBUTORS BE LIABLE */
31/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY */
32/* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, */
33/* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS */
34/* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR */
35/* PERFORMANCE OF THIS SOFTWARE. */
36/* */
37/* --------------------------------------------------------------- */
38/* mlpg.c : speech parameter generation from pdf sequence */
39/* */
40/* 2003/12/26 by Heiga Zen */
41/* --------------------------------------------------------------- */
42/*********************************************************************/
43/* */
44/* Nagoya Institute of Technology, Aichi, Japan, */
45/* and */
46/* Carnegie Mellon University, Pittsburgh, PA */
47/* Copyright (c) 2003-2004,2008 */
48/* All Rights Reserved. */
49/* */
50/* Permission is hereby granted, free of charge, to use and */
51/* distribute this software and its documentation without */
52/* restriction, including without limitation the rights to use, */
53/* copy, modify, merge, publish, distribute, sublicense, and/or */
54/* sell copies of this work, and to permit persons to whom this */
55/* work is furnished to do so, subject to the following conditions: */
56/* */
57/* 1. The code must retain the above copyright notice, this list */
58/* of conditions and the following disclaimer. */
59/* 2. Any modifications must be clearly marked as such. */
60/* 3. Original authors' names are not deleted. */
61/* */
62/* NAGOYA INSTITUTE OF TECHNOLOGY, CARNEGIE MELLON UNIVERSITY, AND */
63/* THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH */
64/* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF */
65/* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NAGOYA INSTITUTE */
66/* OF TECHNOLOGY, CARNEGIE MELLON UNIVERSITY, NOR THE CONTRIBUTORS */
67/* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR */
68/* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR */
69/* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER */
70/* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE */
71/* OR PERFORMANCE OF THIS SOFTWARE. */
72/* */
73/*********************************************************************/
74/* */
75/* Author : Tomoki Toda (tomoki@ics.nitech.ac.jp) */
76/* Date : June 2004 */
77/* */
78/* Modified as a single file for inclusion in festival/flite */
79/* May 2008 awb@cs.cmu.edu */
80/*-------------------------------------------------------------------*/
81/* */
82/* ML-Based Parameter Generation */
83/* */
84/*-------------------------------------------------------------------*/
85
86#include "festival.h"
87#include "simple_mlpg.h"
88#define mlpg_alloc(X,Y)(((Y *)safe_walloc(sizeof(Y)*(X)))) (walloc(Y,X)((Y *)safe_walloc(sizeof(Y)*(X))))
89#define mlpg_freewfree wfree
90#define cst_errmsg(EST_error_where = __null), (*EST_error_func) EST_error(EST_error_where = __null), (*EST_error_func)
91#define cst_error()
92
93#ifdef CMUFLITE
94#include "cst_alloc.h"
95#include "cst_string.h"
96#include "cst_math.h"
97#include "cst_vc.h"
98#include "cst_track.h"
99#include "cst_wave.h"
100#include "cst_mlpg.h"
101
102#define mlpg_alloc(X,Y)(((Y *)safe_walloc(sizeof(Y)*(X)))) (cst_alloc(Y,X))
103#define mlpg_freewfree cst_free
104#endif
105
106static MLPGPARA xmlpgpara_init(int dim, int dim2, int dnum, int clsnum);
107static void xmlpgparafree(MLPGPARA param);
108static double get_like_pdfseq_vit(int dim, int dim2, int dnum, int clsnum,
109 MLPGPARA param,
110 EST_Track *model,
111 XBOOLint dia_flag);
112static void get_dltmat(DMATRIX mat, MLPG_DWin *dw, int dno, DMATRIX dmat);
113
114static double *dcalloc(int x, int xoff);
115static double **ddcalloc(int x, int y, int xoff, int yoff);
116
117/***********************************/
118/* ML using Choleski decomposition */
119/***********************************/
120/* Diagonal Covariance Version */
121static void InitDWin(PStreamChol *pst, const float *dynwin, int fsize);
122static void InitPStreamChol(PStreamChol *pst, const float *dynwin, int fsize,
123 int order, int T);
124static void mlgparaChol(DMATRIX pdf, PStreamChol *pst, DMATRIX mlgp);
125static void mlpgChol(PStreamChol *pst);
126static void calc_R_and_r(PStreamChol *pst, const int m);
127static void Choleski(PStreamChol *pst);
128static void Choleski_forward(PStreamChol *pst);
129static void Choleski_backward(PStreamChol *pst, const int m);
130static double get_gauss_full(long clsidx,
131 DVECTOR vec, // [dim]
132 DVECTOR detvec, // [clsnum]
133 DMATRIX weightmat, // [clsnum][1]
134 DMATRIX meanvec, // [clsnum][dim]
135 DMATRIX invcovmat); // [clsnum * dim][dim]
136static double get_gauss_dia(long clsidx,
137 DVECTOR vec, // [dim]
138 DVECTOR detvec, // [clsnum]
139 DMATRIX weightmat, // [clsnum][1]
140 DMATRIX meanmat, // [clsnum][dim]
141 DMATRIX invcovmat); // [clsnum][dim]
142static double cal_xmcxmc(long clsidx,
143 DVECTOR x,
144 DMATRIX mm, // [num class][dim]
145 DMATRIX cm); // [num class * dim][dim]
146
147const float mlpg_dynwin[] = { -0.5, 0.0, 0.5 };
148#define mlpg_dynwinsize3 3
149
150static MLPGPARA xmlpgpara_init(int dim, int dim2, int dnum,
151 int clsnum)
152{
153 MLPGPARA param;
154
155 // memory allocation
156 param = mlpg_alloc(1,struct MLPGPARA_STRUCT)(((struct MLPGPARA_STRUCT *)safe_walloc(sizeof(struct MLPGPARA_STRUCT
)*(1))))
;
157 param->ov = xdvalloc(dim);
158 param->iuv = NODATA__null;
159 param->iumv = NODATA__null;
160 param->flkv = xdvalloc(dnum);
161 param->stm = NODATA__null;
162 param->dltm = xdmalloc(dnum, dim2);
163 param->pdf = NODATA__null;
164 param->detvec = NODATA__null;
165 param->wght = xdmalloc(clsnum, 1);
166 param->mean = xdmalloc(clsnum, dim);
167 param->cov = NODATA__null;
168 param->clsidxv = NODATA__null;
169 /* dia_flag */
170 param->clsdetv = xdvalloc(1);
171 param->clscov = xdmalloc(1, dim);
172
173 param->vdet = 1.0;
174 param->vm = NODATA__null;
175 param->vv = NODATA__null;
176 param->var = NODATA__null;
177
178 return param;
179}
180
181static void xmlpgparafree(MLPGPARA param)
182{
183 if (param != NODATA__null) {
184 if (param->ov != NODATA__null) xdvfree(param->ov);
185 if (param->iuv != NODATA__null) xdvfree(param->iuv);
186 if (param->iumv != NODATA__null) xdvfree(param->iumv);
187 if (param->flkv != NODATA__null) xdvfree(param->flkv);
188 if (param->stm != NODATA__null) xdmfree(param->stm);
189 if (param->dltm != NODATA__null) xdmfree(param->dltm);
190 if (param->pdf != NODATA__null) xdmfree(param->pdf);
191 if (param->detvec != NODATA__null) xdvfree(param->detvec);
192 if (param->wght != NODATA__null) xdmfree(param->wght);
193 if (param->mean != NODATA__null) xdmfree(param->mean);
194 if (param->cov != NODATA__null) xdmfree(param->cov);
195 if (param->clsidxv != NODATA__null) xlvfree(param->clsidxv);
196 if (param->clsdetv != NODATA__null) xdvfree(param->clsdetv);
197 if (param->clscov != NODATA__null) xdmfree(param->clscov);
198 if (param->vm != NODATA__null) xdvfree(param->vm);
199 if (param->vv != NODATA__null) xdvfree(param->vv);
200 if (param->var != NODATA__null) xdvfree(param->var);
201 mlpg_freewfree(param);
202 }
203
204 return;
205}
206
207static double get_like_pdfseq_vit(int dim, int dim2, int dnum, int clsnum,
208 MLPGPARA param,
209 EST_Track *model,
210 XBOOLint dia_flag)
211{
212 long d, c, k, l, j;
213 double sumgauss;
214 double like = 0.0;
215
216 for (d = 0, like = 0.0; d < dnum; d++) {
217 // read weight and mean sequences
218 param->wght->data[0][0] = 0.9; /* FIXME weights */
219 for (j=0; j<dim; j++)
220 param->mean->data[0][j] = model->a((int)d,(int)((j+1)*2));
221
222 // observation vector
223 for (k = 0; k < dim2; k++) {
224 param->ov->data[k] = param->stm->data[d][k];
225 param->ov->data[k + dim2] = param->dltm->data[d][k];
226 }
227
228 // mixture index
229 c = d;
230 param->clsdetv->data[0] = param->detvec->data[c];
231
232 // calculating likelihood
233 if (dia_flag == XTRUE1) {
234 for (k = 0; k < param->clscov->col; k++)
235 param->clscov->data[0][k] = param->cov->data[c][k];
236 sumgauss = get_gauss_dia(0, param->ov, param->clsdetv,
237 param->wght, param->mean, param->clscov);
238 } else {
239 for (k = 0; k < param->clscov->row; k++)
240 for (l = 0; l < param->clscov->col; l++)
241 param->clscov->data[k][l] =
242 param->cov->data[k + param->clscov->row * c][l];
243 sumgauss = get_gauss_full(0, param->ov, param->clsdetv,
244 param->wght, param->mean, param->clscov);
245 }
246 if (sumgauss <= 0.0) param->flkv->data[d] = -1.0 * INFTY2((double) 1.0e+19);
247 else param->flkv->data[d] = log(sumgauss);
248 like += param->flkv->data[d];
249
250 // estimating U', U'*M
251 if (dia_flag == XTRUE1) {
252 // PDF [U'*M U']
253 for (k = 0; k < dim; k++) {
254 param->pdf->data[d][k] =
255 param->clscov->data[0][k] * param->mean->data[0][k];
256 param->pdf->data[d][k + dim] = param->clscov->data[0][k];
257 }
258 } else {
259 // PDF [U'*M U']
260 for (k = 0; k < dim; k++) {
261 param->pdf->data[d][k] = 0.0;
262 for (l = 0; l < dim; l++) {
263 param->pdf->data[d][k * dim + dim + l] =
264 param->clscov->data[k][l];
265 param->pdf->data[d][k] +=
266 param->clscov->data[k][l] * param->mean->data[0][l];
267 }
268 }
269 }
270 }
271
272 like /= (double)dnum;
273
274 return like;
275}
276
277#if 0
278static double get_like_gv(long dim2, long dnum, MLPGPARA param)
279{
280 long k;
281 double av = 0.0, dif = 0.0;
282 double vlike = -INFTY((double) 1.0e+38);
283
284 if (param->vm != NODATA__null && param->vv != NODATA__null) {
285 for (k = 0; k < dim2; k++)
286 calc_varstats(param->stm->data, k, dnum, &av,
287 &(param->var->data[k]), &dif);
288 vlike = log(get_gauss_dia5(param->vdet, 1.0, param->var,
289 param->vm, param->vv));
290 }
291
292 return vlike;
293}
294
295static void sm_mvav(DMATRIX mat, long hlen)
296{
297 long k, l, m, p;
298 double d, sd;
299 DVECTOR vec = NODATA__null;
300 DVECTOR win = NODATA__null;
301
302 vec = xdvalloc(mat->row);
303
304 // smoothing window
305 win = xdvalloc(hlen * 2 + 1);
306 for (k = 0, d = 1.0, sd = 0.0; k < hlen; k++, d += 1.0) {
307 win->data[k] = d; win->data[win->length - k - 1] = d;
308 sd += d + d;
309 }
310 win->data[k] = d; sd += d;
311 for (k = 0; k < win->length; k++) win->data[k] /= sd;
312
313 for (l = 0; l < mat->col; l++) {
314 for (k = 0; k < mat->row; k++) {
315 for (m = 0, vec->data[k] = 0.0; m < win->length; m++) {
316 p = k - hlen + m;
317 if (p >= 0 && p < mat->row)
318 vec->data[k] += mat->data[p][l] * win->data[m];
319 }
320 }
321 for (k = 0; k < mat->row; k++) mat->data[k][l] = vec->data[k];
322 }
323
324 xdvfree(win);
325 xdvfree(vec);
326
327 return;
328}
329#endif
330
331static void get_dltmat(DMATRIX mat, MLPG_DWin *dw, int dno, DMATRIX dmat)
332{
333 int i, j, k, tmpnum;
334
335 tmpnum = (int)mat->row - dw->width[dno][WRIGHT1];
336 for (k = dw->width[dno][WRIGHT1]; k < tmpnum; k++) // time index
337 for (i = 0; i < (int)mat->col; i++) // dimension index
338 for (j = dw->width[dno][WLEFT0], dmat->data[k][i] = 0.0;
339 j <= dw->width[dno][WRIGHT1]; j++)
340 dmat->data[k][i] += mat->data[k + j][i] * dw->coef[dno][j];
341
342 for (i = 0; i < (int)mat->col; i++) { // dimension index
343 for (k = 0; k < dw->width[dno][WRIGHT1]; k++) // time index
344 for (j = dw->width[dno][WLEFT0], dmat->data[k][i] = 0.0;
345 j <= dw->width[dno][WRIGHT1]; j++)
346 if (k + j >= 0)
347 dmat->data[k][i] += mat->data[k + j][i] * dw->coef[dno][j];
348 else
349 dmat->data[k][i] += (2.0 * mat->data[0][i] - mat->data[-k - j][i]) * dw->coef[dno][j];
350 for (k = tmpnum; k < (int)mat->row; k++) // time index
351 for (j = dw->width[dno][WLEFT0], dmat->data[k][i] = 0.0;
352 j <= dw->width[dno][WRIGHT1]; j++)
353 if (k + j < (int)mat->row)
354 dmat->data[k][i] += mat->data[k + j][i] * dw->coef[dno][j];
355 else
356 dmat->data[k][i] += (2.0 * mat->data[mat->row - 1][i] - mat->data[mat->row - k - j + mat->row - 2][i]) * dw->coef[dno][j];
357 }
358
359 return;
360}
361
362
363static double *dcalloc(int x, int xoff)
364{
365 double *ptr;
366
367 ptr = mlpg_alloc(x,double)(((double *)safe_walloc(sizeof(double)*(x))));
368 /* ptr += xoff; */ /* Just not going to allow this */
369 return(ptr);
370}
371
372static double **ddcalloc(int x, int y, int xoff, int yoff)
373{
374 double **ptr;
375 register int i;
376
377 ptr = mlpg_alloc(x,double *)(((double * *)safe_walloc(sizeof(double *)*(x))));
378 for (i = 0; i < x; i++) ptr[i] = dcalloc(y, yoff);
379 /* ptr += xoff; */ /* Just not going to allow this */
380 return(ptr);
381}
382
383/////////////////////////////////////
384// ML using Choleski decomposition //
385/////////////////////////////////////
386static void InitDWin(PStreamChol *pst, const float *dynwin, int fsize)
387{
388 int i,j;
389 int leng;
390
391 pst->dw.num = 1; // only static
392 if (dynwin) {
393 pst->dw.num = 2; // static + dyn
394 }
395 // memory allocation
396 pst->dw.width = mlpg_alloc(pst->dw.num,int *)(((int * *)safe_walloc(sizeof(int *)*(pst->dw.num))));
397 for (i = 0; i < pst->dw.num; i++)
398 pst->dw.width[i] = mlpg_alloc(2,int)(((int *)safe_walloc(sizeof(int)*(2))));
399
400 pst->dw.coef = mlpg_alloc(pst->dw.num, double *)(((double * *)safe_walloc(sizeof(double *)*(pst->dw.num)))
)
;
401 pst->dw.coef_ptrs = mlpg_alloc(pst->dw.num, double *)(((double * *)safe_walloc(sizeof(double *)*(pst->dw.num)))
)
;
402 // window for static parameter WLEFT = 0, WRIGHT = 1
403 pst->dw.width[0][WLEFT0] = pst->dw.width[0][WRIGHT1] = 0;
404 pst->dw.coef_ptrs[0] = mlpg_alloc(1,double)(((double *)safe_walloc(sizeof(double)*(1))));
405 pst->dw.coef[0] = pst->dw.coef_ptrs[0];
406 pst->dw.coef[0][0] = 1.0;
407
408 // set delta coefficients
409 for (i = 1; i < pst->dw.num; i++) {
410 pst->dw.coef_ptrs[i] = mlpg_alloc(fsize, double)(((double *)safe_walloc(sizeof(double)*(fsize))));
411 pst->dw.coef[i] = pst->dw.coef_ptrs[i];
412 for (j=0; j<fsize; j++) /* FIXME make dynwin doubles for memmove */
413 pst->dw.coef[i][j] = (double)dynwin[j];
414 // set pointer
415 leng = fsize / 2; // L (fsize = 2 * L + 1)
416 pst->dw.coef[i] += leng; // [L] -> [0] center
417 pst->dw.width[i][WLEFT0] = -leng; // -L left
418 pst->dw.width[i][WRIGHT1] = leng; // L right
419 if (fsize % 2 == 0) pst->dw.width[i][WRIGHT1]--;
420 }
421
422 pst->dw.maxw[WLEFT0] = pst->dw.maxw[WRIGHT1] = 0;
423 for (i = 0; i < pst->dw.num; i++) {
424 if (pst->dw.maxw[WLEFT0] > pst->dw.width[i][WLEFT0])
425 pst->dw.maxw[WLEFT0] = pst->dw.width[i][WLEFT0];
426 if (pst->dw.maxw[WRIGHT1] < pst->dw.width[i][WRIGHT1])
427 pst->dw.maxw[WRIGHT1] = pst->dw.width[i][WRIGHT1];
428 }
429
430 return;
431}
432
433static void InitPStreamChol(PStreamChol *pst, const float *dynwin, int fsize,
434 int order, int T)
435{
436 // order of cepstrum
437 pst->order = order;
438
439 // windows for dynamic feature
440 InitDWin(pst, dynwin, fsize);
441
442 // dimension of observed vector
443 pst->vSize = (pst->order + 1) * pst->dw.num; // odim = dim * (1--3)
444
445 // memory allocation
446 pst->T = T; // number of frames
447 pst->width = pst->dw.maxw[WRIGHT1] * 2 + 1; // width of R
448 pst->mseq = ddcalloc(T, pst->vSize, 0, 0); // [T][odim]
449 pst->ivseq = ddcalloc(T, pst->vSize, 0, 0); // [T][odim]
450 pst->R = ddcalloc(T, pst->width, 0, 0); // [T][width]
451 pst->r = dcalloc(T, 0); // [T]
452 pst->g = dcalloc(T, 0); // [T]
453 pst->c = ddcalloc(T, pst->order + 1, 0, 0); // [T][dim]
454
455 return;
456}
457
458static void mlgparaChol(DMATRIX pdf, PStreamChol *pst, DMATRIX mlgp)
459{
460 int t, d;
461
462 // error check
463 if (pst->vSize * 2 != pdf->col || pst->order + 1 != mlgp->col) {
464 cst_errmsg(EST_error_where = __null), (*EST_error_func)("Error mlgparaChol: Different dimension\n");
465 cst_error();
466 }
467
468 // mseq: U^{-1}*M, ifvseq: U^{-1}
469 for (t = 0; t < pst->T; t++) {
470 for (d = 0; d < pst->vSize; d++) {
471 pst->mseq[t][d] = pdf->data[t][d];
472 pst->ivseq[t][d] = pdf->data[t][pst->vSize + d];
473 }
474 }
475
476 // ML parameter generation
477 mlpgChol(pst);
478
479 // extracting parameters
480 for (t = 0; t < pst->T; t++)
481 for (d = 0; d <= pst->order; d++)
482 mlgp->data[t][d] = pst->c[t][d];
483
484 return;
485}
486
487// generate parameter sequence from pdf sequence using Choleski decomposition
488static void mlpgChol(PStreamChol *pst)
489{
490 register int m;
491
492 // generating parameter in each dimension
493 for (m = 0; m <= pst->order; m++) {
494 calc_R_and_r(pst, m);
495 Choleski(pst);
496 Choleski_forward(pst);
497 Choleski_backward(pst, m);
498 }
499
500 return;
501}
502
503//------ parameter generation fuctions
504// calc_R_and_r: calculate R = W'U^{-1}W and r = W'U^{-1}M
505static void calc_R_and_r(PStreamChol *pst, const int m)
506{
507 register int i, j, k, l, n;
508 double wu;
509
510 for (i = 0; i < pst->T; i++) {
511 pst->r[i] = pst->mseq[i][m];
512 pst->R[i][0] = pst->ivseq[i][m];
513
514 for (j = 1; j < pst->width; j++) pst->R[i][j] = 0.0;
515
516 for (j = 1; j < pst->dw.num; j++) {
517 for (k = pst->dw.width[j][0]; k <= pst->dw.width[j][1]; k++) {
518 n = i + k;
519 if (n >= 0 && n < pst->T && pst->dw.coef[j][-k] != 0.0) {
520 l = j * (pst->order + 1) + m;
521 pst->r[i] += pst->dw.coef[j][-k] * pst->mseq[n][l];
522 wu = pst->dw.coef[j][-k] * pst->ivseq[n][l];
523
524 for (l = 0; l < pst->width; l++) {
525 n = l-k;
526 if (n <= pst->dw.width[j][1] && i + l < pst->T &&
527 pst->dw.coef[j][n] != 0.0)
528 pst->R[i][l] += wu * pst->dw.coef[j][n];
529 }
530 }
531 }
532 }
533 }
534
535 return;
536}
537
538// Choleski: Choleski factorization of Matrix R
539static void Choleski(PStreamChol *pst)
540{
541 register int t, j, k;
542
543 pst->R[0][0] = sqrt(pst->R[0][0]);
544
545 for (j = 1; j < pst->width; j++) pst->R[0][j] /= pst->R[0][0];
546
547 for (t = 1; t < pst->T; t++) {
548 for (j = 1; j < pst->width; j++)
549 if (t - j >= 0)
550 pst->R[t][0] -= pst->R[t - j][j] * pst->R[t - j][j];
551
552 pst->R[t][0] = sqrt(pst->R[t][0]);
553
554 for (j = 1; j < pst->width; j++) {
555 for (k = 0; k < pst->dw.maxw[WRIGHT1]; k++)
556 if (j != pst->width - 1)
557 pst->R[t][j] -=
558 pst->R[t - k - 1][j - k] * pst->R[t - k - 1][j + 1];
559
560 pst->R[t][j] /= pst->R[t][0];
561 }
562 }
563
564 return;
565}
566
567// Choleski_forward: forward substitution to solve linear equations
568static void Choleski_forward(PStreamChol *pst)
569{
570 register int t, j;
571 double hold;
572
573 pst->g[0] = pst->r[0] / pst->R[0][0];
574
575 for (t=1; t < pst->T; t++) {
576 hold = 0.0;
577 for (j = 1; j < pst->width; j++)
578 if (t - j >= 0 && pst->R[t - j][j] != 0.0)
579 hold += pst->R[t - j][j] * pst->g[t - j];
580 pst->g[t] = (pst->r[t] - hold) / pst->R[t][0];
581 }
582
583 return;
584}
585
586// Choleski_backward: backward substitution to solve linear equations
587static void Choleski_backward(PStreamChol *pst, const int m)
588{
589 register int t, j;
590 double hold;
591
592 pst->c[pst->T - 1][m] = pst->g[pst->T - 1] / pst->R[pst->T - 1][0];
593
594 for (t = pst->T - 2; t >= 0; t--) {
595 hold = 0.0;
596 for (j = 1; j < pst->width; j++)
597 if (t + j < pst->T && pst->R[t][j] != 0.0)
598 hold += pst->R[t][j] * pst->c[t + j][m];
599 pst->c[t][m] = (pst->g[t] - hold) / pst->R[t][0];
600 }
601
602 return;
603}
604
605////////////////////////////////////
606// ML Considering Global Variance //
607////////////////////////////////////
608#if 0
609static void varconv(double **c, const int m, const int T, const double var)
610{
611 register int n;
612 double sd, osd;
613 double oav = 0.0, ovar = 0.0, odif = 0.0;
614
615 calc_varstats(c, m, T, &oav, &ovar, &odif);
616 osd = sqrt(ovar); sd = sqrt(var);
617 for (n = 0; n < T; n++)
618 c[n][m] = (c[n][m] - oav) / osd * sd + oav;
619
620 return;
621}
622
623static void calc_varstats(double **c, const int m, const int T,
624 double *av, double *var, double *dif)
625{
626 register int i;
627 register double d;
628
629 *av = 0.0;
630 *var = 0.0;
631 *dif = 0.0;
632 for (i = 0; i < T; i++) *av += c[i][m];
633 *av /= (double)T;
634 for (i = 0; i < T; i++) {
635 d = c[i][m] - *av;
636 *var += d * d; *dif += d;
637 }
638 *var /= (double)T;
639
640 return;
641}
642
643// Diagonal Covariance Version
644static void mlgparaGrad(DMATRIX pdf, PStreamChol *pst, DMATRIX mlgp, const int max,
645 double th, double e, double alpha, DVECTOR vm, DVECTOR vv,
646 XBOOLint nrmflag, XBOOLint extvflag)
647{
648 int t, d;
649
650 // error check
651 if (pst->vSize * 2 != pdf->col || pst->order + 1 != mlgp->col) {
652 cst_errmsg(EST_error_where = __null), (*EST_error_func)("Error mlgparaChol: Different dimension\n");
653 cst_error();
654 }
655
656 // mseq: U^{-1}*M, ifvseq: U^{-1}
657 for (t = 0; t < pst->T; t++) {
658 for (d = 0; d < pst->vSize; d++) {
659 pst->mseq[t][d] = pdf->data[t][d];
660 pst->ivseq[t][d] = pdf->data[t][pst->vSize + d];
661 }
662 }
663
664 // ML parameter generation
665 mlpgChol(pst);
666
667 // extend variance
668 if (extvflag == XTRUE1)
669 for (d = 0; d <= pst->order; d++)
670 varconv(pst->c, d, pst->T, vm->data[d]);
671
672 // estimating parameters
673 mlpgGrad(pst, max, th, e, alpha, vm, vv, nrmflag);
674
675 // extracting parameters
676 for (t = 0; t < pst->T; t++)
677 for (d = 0; d <= pst->order; d++)
678 mlgp->data[t][d] = pst->c[t][d];
679
680 return;
681}
682
683// generate parameter sequence from pdf sequence using gradient
684static void mlpgGrad(PStreamChol *pst, const int max, double th, double e,
685 double alpha, DVECTOR vm, DVECTOR vv, XBOOLint nrmflag)
686{
687 register int m, i, t;
688 double diff, n, dth;
689
690 if (nrmflag == XTRUE1)
691 n = (double)(pst->T * pst->vSize) / (double)(vm->length);
692 else n = 1.0;
693
694 // generating parameter in each dimension
695 for (m = 0; m <= pst->order; m++) {
696 calc_R_and_r(pst, m);
697 dth = th * sqrt(vm->data[m]);
698 for (i = 0; i < max; i++) {
699 calc_grad(pst, m);
700 if (vm != NODATA__null && vv != NODATA__null)
701 calc_vargrad(pst, m, alpha, n, vm->data[m], vv->data[m]);
702 for (t = 0, diff = 0.0; t < pst->T; t++) {
703 diff += pst->g[t] * pst->g[t];
704 pst->c[t][m] += e * pst->g[t];
705 }
706 diff = sqrt(diff / (double)pst->T);
707 if (diff < dth || diff == 0.0) break;
708 }
709 }
710
711 return;
712}
713
714// calc_grad: calculate -RX + r = -W'U^{-1}W * X + W'U^{-1}M
715void calc_grad(PStreamChol *pst, const int m)
716{
717 register int i, j;
718
719 for (i = 0; i < pst->T; i++) {
720 pst->g[i] = pst->r[i] - pst->c[i][m] * pst->R[i][0];
721 for (j = 1; j < pst->width; j++) {
722 if (i + j < pst->T) pst->g[i] -= pst->c[i + j][m] * pst->R[i][j];
723 if (i - j >= 0) pst->g[i] -= pst->c[i - j][m] * pst->R[i - j][j];
724 }
725 }
726
727 return;
728}
729
730static void calc_vargrad(PStreamChol *pst, const int m, double alpha, double n,
731 double vm, double vv)
732{
733 register int i;
734 double vg, w1, w2;
735 double av = 0.0, var = 0.0, dif = 0.0;
736
737 if (alpha > 1.0 || alpha < 0.0) {
738 w1 = 1.0; w2 = 1.0;
739 } else {
740 w1 = alpha; w2 = 1.0 - alpha;
741 }
742
743 calc_varstats(pst->c, m, pst->T, &av, &var, &dif);
744
745 for (i = 0; i < pst->T; i++) {
746 vg = -(var - vm) * (pst->c[i][m] - av) * vv * 2.0 / (double)pst->T;
747 pst->g[i] = w1 * pst->g[i] / n + w2 * vg;
748 }
749
750 return;
751}
752#endif
753
754// diagonal covariance
755static DVECTOR xget_detvec_diamat2inv(DMATRIX covmat) // [num class][dim]
756{
757 long dim, clsnum;
758 long i, j;
759 double det;
760 DVECTOR detvec = NODATA__null;
761
762 clsnum = covmat->row;
763 dim = covmat->col;
764 // memory allocation
765 detvec = xdvalloc(clsnum);
766 for (i = 0; i < clsnum; i++) {
767 for (j = 0, det = 1.0; j < dim; j++) {
768 det *= covmat->data[i][j];
769 if (det > 0.0) {
770 covmat->data[i][j] = 1.0 / covmat->data[i][j];
771 } else {
772 cst_errmsg(EST_error_where = __null), (*EST_error_func)("error:(class %ld) determinant <= 0, det = %f\n", i, det);
773 xdvfree(detvec);
774 return NODATA__null;
775 }
776 }
777 detvec->data[i] = det;
778 }
779
780 return detvec;
781}
782
783static double get_gauss_full(long clsidx,
784 DVECTOR vec, // [dim]
785 DVECTOR detvec, // [clsnum]
786 DMATRIX weightmat, // [clsnum][1]
787 DMATRIX meanvec, // [clsnum][dim]
788 DMATRIX invcovmat) // [clsnum * dim][dim]
789{
790 double gauss;
791
792 if (detvec->data[clsidx] <= 0.0) {
793 cst_errmsg(EST_error_where = __null), (*EST_error_func)("#error: det <= 0.0\n");
794 cst_error();
795 }
796
797 gauss = weightmat->data[clsidx][0]
798 / sqrt(pow(2.0 * PI3.14159265358979323846, (double)vec->length) * detvec->data[clsidx])
799 * exp(-1.0 * cal_xmcxmc(clsidx, vec, meanvec, invcovmat) / 2.0);
800
801 return gauss;
802}
803
804static double cal_xmcxmc(long clsidx,
805 DVECTOR x,
806 DMATRIX mm, // [num class][dim]
807 DMATRIX cm) // [num class * dim][dim]
808{
809 long clsnum, k, l, b, dim;
810 double *vec = NULL__null;
811 double td, d;
812
813 dim = x->length;
814 clsnum = mm->row;
815 b = clsidx * dim;
816 if (mm->col != dim || cm->col != dim || clsnum * dim != cm->row) {
817 cst_errmsg(EST_error_where = __null), (*EST_error_func)("Error cal_xmcxmc: different dimension\n");
818 cst_error();
819 }
820
821 // memory allocation
822 vec = mlpg_alloc((int)dim, double)(((double *)safe_walloc(sizeof(double)*((int)dim))));
823 for (k = 0; k < dim; k++) vec[k] = x->data[k] - mm->data[clsidx][k];
824 for (k = 0, d = 0.0; k < dim; k++) {
825 for (l = 0, td = 0.0; l < dim; l++) td += vec[l] * cm->data[l + b][k];
826 d += td * vec[k];
827 }
828 // memory free
829 mlpg_freewfree(vec); vec = NULL__null;
830
831 return d;
832}
833
834#if 0
835// diagonal covariance
836static double get_gauss_dia5(double det,
837 double weight,
838 DVECTOR vec, // dim
839 DVECTOR meanvec, // dim
840 DVECTOR invcovvec) // dim
841{
842 double gauss, sb;
843 long k;
844
845 if (det <= 0.0) {
846 cst_errmsg(EST_error_where = __null), (*EST_error_func)("#error: det <= 0.0\n");
847 cst_error();
848 }
849
850 for (k = 0, gauss = 0.0; k < vec->length; k++) {
851 sb = vec->data[k] - meanvec->data[k];
852 gauss += sb * invcovvec->data[k] * sb;
853 }
854
855 gauss = weight / sqrt(pow(2.0 * PI3.14159265358979323846, (double)vec->length) * det)
856 * exp(-gauss / 2.0);
857
858 return gauss;
859}
860#endif
861
862static double get_gauss_dia(long clsidx,
863 DVECTOR vec, // [dim]
864 DVECTOR detvec, // [clsnum]
865 DMATRIX weightmat, // [clsnum][1]
866 DMATRIX meanmat, // [clsnum][dim]
867 DMATRIX invcovmat) // [clsnum][dim]
868{
869 double gauss, sb;
870 long k;
871
872 if (detvec->data[clsidx] <= 0.0) {
873 cst_errmsg(EST_error_where = __null), (*EST_error_func)("#error: det <= 0.0\n");
874 cst_error();
875 }
876
877 for (k = 0, gauss = 0.0; k < vec->length; k++) {
878 sb = vec->data[k] - meanmat->data[clsidx][k];
879 gauss += sb * invcovmat->data[clsidx][k] * sb;
880 }
881
882 gauss = weightmat->data[clsidx][0]
883 / sqrt(pow(2.0 * PI3.14159265358979323846, (double)vec->length) * detvec->data[clsidx])
884 * exp(-gauss / 2.0);
885
886 return gauss;
887}
888
889static void pst_free(PStreamChol *pst)
890{
891 int i;
892
893 for (i=0; i<pst->dw.num; i++)
894 mlpg_freewfree(pst->dw.width[i]);
895 mlpg_freewfree(pst->dw.width); pst->dw.width = NULL__null;
896 for (i=0; i<pst->dw.num; i++)
897 mlpg_freewfree(pst->dw.coef_ptrs[i]);
898 mlpg_freewfree(pst->dw.coef); pst->dw.coef = NULL__null;
899 mlpg_freewfree(pst->dw.coef_ptrs); pst->dw.coef_ptrs = NULL__null;
900
901 for (i=0; i<pst->T; i++)
902 mlpg_freewfree(pst->mseq[i]);
903 mlpg_freewfree(pst->mseq);
904 for (i=0; i<pst->T; i++)
905 mlpg_freewfree(pst->ivseq[i]);
906 mlpg_freewfree(pst->ivseq);
907 for (i=0; i<pst->T; i++)
908 mlpg_freewfree(pst->R[i]);
909 mlpg_freewfree(pst->R);
910 mlpg_freewfree(pst->r);
911 mlpg_freewfree(pst->g);
912 for (i=0; i<pst->T; i++)
913 mlpg_freewfree(pst->c[i]);
914 mlpg_freewfree(pst->c);
915
916 return;
917}
918
919LISP mlpg(LISP ltrack)
920{
921 /* Generate an (mcep) track using Maximum Likelihood Parameter Generation */
922 MLPGPARA param = NODATA__null;
923 EST_Track *param_track, *out;
924 int dim, dim_st;
925 float like;
926 int i,j;
927 int nframes;
928 PStreamChol pst;
929
930 if ((ltrack == NULL__null) ||
931 (TYPEP(ltrack,tc_string)( (ltrack != __null) && ((((ltrack) == ((struct obj *
) 0)) ? 0 : ((*(ltrack)).type)) == (13)) )
&&
932 (streq(get_c_string(ltrack),"nil")(strcmp(get_c_string(ltrack),"nil")==0))))
933 return NIL((struct obj *) 0);
934
935 param_track = track(ltrack);
936
937 nframes = param_track->num_frames();
938 dim = (param_track->num_channels()/2)-1;
939 dim_st = dim/2; /* dim2 in original code */
940 out = new EST_Track();
941 out->copy_setup(*param_track);
942 out->resize(nframes,dim_st+1);
943
944 param = xmlpgpara_init(dim,dim_st,nframes,nframes);
945
946 // mixture-index sequence
947 param->clsidxv = xlvalloc(nframes);
948 for (i=0; i<nframes; i++)
949 param->clsidxv->data[i] = i;
950
951 // initial static feature sequence
952 param->stm = xdmalloc(nframes,dim_st);
953 for (i=0; i<nframes; i++)
954 {
955 for (j=0; j<dim_st; j++)
956 param->stm->data[i][j] = param_track->a(i,(j+1)*2);
957 }
958
959 /* Load cluster means */
960 for (i=0; i<nframes; i++)
961 for (j=0; j<dim_st; j++)
962 param->mean->data[i][j] = param_track->a(i,(j+1)*2);
963
964 /* GMM parameters diagonal covariance */
965 InitPStreamChol(&pst, mlpg_dynwin, mlpg_dynwinsize3, dim_st-1, nframes);
966 param->pdf = xdmalloc(nframes,dim*2);
967 param->cov = xdmalloc(nframes,dim);
968 for (i=0; i<nframes; i++)
969 for (j=0; j<dim; j++)
970 param->cov->data[i][j] =
971 param_track->a(i,(j+1)*2+1) *
972 param_track->a(i,(j+1)*2+1);
973 param->detvec = xget_detvec_diamat2inv(param->cov);
974
975 /* global variance parameters */
976 /* TBD get_gv_mlpgpara(param, vmfile, vvfile, dim2, msg_flag); */
977
978 if (nframes > 0)
979 {
980 get_dltmat(param->stm, &pst.dw, 1, param->dltm);
981
982 like = get_like_pdfseq_vit(dim, dim_st, nframes, nframes, param,
Value stored to 'like' is never read
983 param_track, XTRUE1);
984
985 /* vlike = get_like_gv(dim2, dnum, param); */
986
987 mlgparaChol(param->pdf, &pst, param->stm);
988 }
989
990 /* Put the answer back into the output track */
991 for (i=0; i<nframes; i++)
992 {
993 out->t(i) = param_track->t(i);
994 out->a(i,0) = param_track->a(i,0); /* F0 */
995 for (j=0; j<dim_st; j++)
996 {
997 out->a(i,j+1) = param->stm->data[i][j];
998 }
999 }
1000
1001 // memory free
1002 xmlpgparafree(param);
1003 pst_free(&pst);
1004
1005 return siod(out);
1006}
1007