/** * @file gprune_common.c * * * @brief 混合ガウス分布計算: Gaussian pruning (共通部) * * ここには Gaussian pruningにおいて各アルゴリズムで共通に用いられる * キャッシュ操作関数などが含まれています. * * * * @brief Calculate probability of a set of Gaussian densities by * Gaussian pruning: common functions * * This file contains functions concerning codebook level cache * manipulation, commonly used for the Gaussian pruning functions. * * * @author Akinobu LEE * @date Fri Feb 18 18:10:58 2005 * * $Revision: 1.4 $ * */ /* * 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 /** * Find where the new value should be inserted to the OP_cacled_score, * already sorted by score, using binary search. * * @param score [in] the new score to be inserted * @param len [in] length of data in OP_calced_score * * @return the insertion point. */ static int find_insert_point(LOGPROB *calced_score, LOGPROB score, int len) { /* binary search on score */ int left = 0; int right = len - 1; int mid; while (left < right) { mid = (left + right) / 2; if (calced_score[mid] > score) { left = mid + 1; } else { right = mid; } } return(left); } /** * @brief Store a score to the current list of computed Gaussians. * * Store the calculated score of a Gaussian to OP_calced_score, with its * corresponding mixture id to OP_calced_id. * * The OP_calced_score and OP_calced_id always holds the * (OP_gprune_num)-best scores and ids. If the number of stored * Gaussian from start has reached OP_gprune_num and the given score is * below the bottom, it will be dropped. Else, the new * score will be inserted and the bottom will be dropped from the list. * * The OP_calced_score will always kept sorted by the scores. * * @param wrk [i/o] HMM computation work area * @param id [in] mixture id of the Gaussian to store * @param score [in] score of the Gaussian to store * @param len [in] current number of stored scores in OP_calced_score * * @return the resulting number of stored scores in OP_calced_score. */ int cache_push(HMMWork *wrk, int id, LOGPROB score, int len) { int insertp; LOGPROB *calced_score; int *calced_id; calced_score = wrk->OP_calced_score; calced_id = wrk->OP_calced_id; if (len == 0) { /* first one */ calced_score[0] = score; calced_id[0] = id; return(1); } if (calced_score[len-1] >= score) { /* bottom */ if (len < wrk->OP_gprune_num) { /* append to bottom */ calced_score[len] = score; calced_id[len] = id; len++; } return len; } if (calced_score[0] < score) { insertp = 0; } else { insertp = find_insert_point(calced_score, score, len); } if (len < wrk->OP_gprune_num) { memmove(&(calced_score[insertp+1]), &(calced_score[insertp]), sizeof(LOGPROB)*(len - insertp)); memmove(&(calced_id[insertp+1]), &(calced_id[insertp]), sizeof(int)*(len - insertp)); } else if (insertp < len - 1) { memmove(&(calced_score[insertp+1]), &(calced_score[insertp]), sizeof(LOGPROB)*(len - insertp - 1)); memmove(&(calced_id[insertp+1]), &(calced_id[insertp]), sizeof(int)*(len - insertp - 1)); } calced_score[insertp] = score; calced_id[insertp] = id; if (len < wrk->OP_gprune_num) len++; return(len); }