/** * @file gprune_none.c * * * @brief 混合ガウス分布計算: Gaussian pruning 無し * * gprune_none()は混合ガウス分布集合の計算ルーチンの一つです. * pruningなどを行なわずに全てのGauss分布について出力確率を求めます. * tied-mixtureでないモデルではこの関数がデフォルトで用いられます. * また "-gprune none" を指定することでも選択することができます. * * outprob_init() によって gprune_none() が関数ポインタ @a compute_gaussset に * セットされ,それが calc_tied_mix() またはcalc_mix() から呼び出されます. * * * * @brief Calculate probability of a set of Gaussian densities (no pruning) * * gprune_none() is one of the functions to compute output probability of * a set of Gaussian densities. This function does no pruning, just computing * each Gaussian density one by one. For non tied-mixture model, this function * is used as default. Specifying "-gprune none" at runtime can also select * this function. * * gprune_none() will be used by calling outprob_init() to set its pointer * to the global variable @a compute_gaussset. Then it will be called from * calc_tied_mix() or calc_mix(). * * * @author Akinobu LEE * @date Thu Feb 17 05:09:46 2005 * * $Revision: 1.6 $ * */ /* * Copyright (c) 1991-2012 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology * All rights reserved */ #include #include #include #include #include /** * Calculate probability of a Gaussian density against input * vector on OP_vec. * * @param wrk [i/o] HMM computation work area * @param binfo [in] a Gaussian density * * @return the output log probability. */ LOGPROB compute_g_base(HMMWork *wrk, HTK_HMM_Dens *binfo) { VECT tmp, x; VECT *mean; VECT *var; VECT *vec = wrk->OP_vec; short veclen = wrk->OP_veclen; if (binfo == NULL) return(LOG_ZERO); mean = binfo->mean; var = binfo->var->vec; tmp = binfo->gconst; for (; veclen > 0; veclen--) { #ifdef ENABLE_MSD if (*vec == LZERO) { vec++; continue; } #endif x = *(vec++) - *(mean++); tmp += x * x * *(var++); } return(tmp * -0.5); } /** * Initialize and setup work area for Gaussian computation * * @param wrk [i/o] HMM computation work area * * @return TRUE on success, FALSE on failure. */ boolean gprune_none_init(HMMWork *wrk) { /* maximum Gaussian set size = maximum mixture size * nstream */ wrk->OP_calced_maxnum = wrk->OP_hmminfo->maxmixturenum * wrk->OP_nstream; wrk->OP_calced_score = (LOGPROB *)mymalloc(sizeof(LOGPROB) * wrk->OP_calced_maxnum); wrk->OP_calced_id = (int *)mymalloc(sizeof(int) * wrk->OP_calced_maxnum); /* force gprune_num to the max number */ wrk->OP_gprune_num = wrk->OP_calced_maxnum; return TRUE; } /** * Free gprune_none related work area. * * @param wrk [i/o] HMM computation work area * */ void gprune_none_free(HMMWork *wrk) { free(wrk->OP_calced_score); free(wrk->OP_calced_id); } /** * @brief Compute a set of Gaussians with no pruning * * The calculated scores will be stored to OP_calced_score, with its * corresponding mixture id to OP_calced_id. * The number of calculated mixtures is also stored in OP_calced_num. * * This can be called from calc_tied_mix() or calc_mix(). * * @param wrk [i/o] HMM computation work area * @param g [in] set of Gaussian densities to compute the output probability. * @param num [in] length of above * @param last_id [in] ID list of N-best mixture in previous input frame, * or NULL if not exist * @param lnum [in] length of last_id */ void gprune_none(HMMWork *wrk, HTK_HMM_Dens **g, int num, int *last_id, int lnum) { int i; HTK_HMM_Dens *dens; LOGPROB *prob = wrk->OP_calced_score; int *id = wrk->OP_calced_id; #ifdef ENABLE_MSD int valid_dim; int calced_num; #endif #ifdef ENABLE_MSD valid_dim = 0; for(i=0; iOP_veclen; i++) { if (wrk->OP_vec[i] != LZERO) valid_dim++; } calced_num = 0; for(i=0; imeanlen != valid_dim) continue; if (dens->meanlen == 0) { *(prob++) = 0.0; } else { *(prob++) = compute_g_base(wrk, dens); } *(id++) = i; calced_num++; } if (calced_num == 0) { jlog("Error: MSD: input data dim = %d / %d, but no Gaussian defined for it\n", valid_dim, wrk->OP_veclen); jlog("Error: MSD: Gaussian dimensions in this mixture:"); for(i=0;imeanlen); } jlog("\n"); } wrk->OP_calced_num = calced_num; #else for(i=0; iOP_calced_num = num; #endif }