// file: $isip/class/search/NBestPath/nbstp_05.cc // version: $Id: nbstp_05.cc 9332 2003-11-03 14:27:14Z alphonso $ // // isip include files // #include "NBestPath.h" // method: clear // // arguments: // Integral::CMODE cmode: (input) clear mode // // return: a bool8 value indicating status // // this method clears the model. in RETAIN mode, the virtual model pointer // is maintained; all other modes reset the virtual model pointer to the // default value. // bool8 NBestPath::clear(Integral::CMODE ctype_a) { // clear the data members // frame_index_d = DEF_FRAME_INDEX; max_score_d = DEF_MAX_SCORE; // clear the contents of the list // paths_d.clear(Integral::FREE); // exit gracefully // return true; } // method: insertPath // // arguments: // NBestPath* node: (input) partial path // // return: a bool8 indicating status // // this method adds a partial paths to the list // bool8 NBestPath::insertPath(NBestNode* path_a) { // define local variables // float32 score = 0.0; bool8 is_inserted = false; NBestNode* nnode = (NBestNode*)NULL; // when the path to add is null return ungracefully // if (path_a == (NBestNode*)NULL) { return false; } // retrieve the new path score // float32 new_score = path_a->getPathScore(); // insert the new path at the right place // for (bool8 more = paths_d.gotoFirst(); more; more = paths_d.gotoNext()) { // retrieve the current node and the corresponding score // nnode = paths_d.getCurr(); score = nnode->getPathScore(); // insert the new path if it has a better score // if (new_score > score) { is_inserted = true; paths_d.insert(path_a, true); break; } } // make sure the node was inserted // if (!is_inserted) { paths_d.insertLast(path_a); } // exit gracefully // return true; } // method: growPaths // // arguments: // NBestPath**& path_list: (input) partial paths // float32 scale: (input) language model scale // float32 penalty: (input) symbol insertion penalty // int32 max_paths: (input) max number of hypothesis // float32 beam: (input) beam pruning threshold // // return: a bool8 indicating status // // this method extend partial paths // bool8 NBestPath::growPaths(NBestPath**& path_list_a, float32 scale_a, float32 penalty_a, int32 max_paths_a, float32 beam_a) { // define local variables // int32 frame_index = 0; float32 score = 0.0; float32 lm_score = 0.0; float32 ac_score = 0.0; NBestNode* nnode = (NBestNode*)NULL; NBestNode* new_nbest_node = (NBestNode*)NULL; SymbolGraphNode* curr_node = (SymbolGraphNode*)NULL; SymbolGraphNode* next_node = (SymbolGraphNode*)NULL; // loop through the partial path list // for (bool8 more = paths_d.gotoFirst(); more; more = paths_d.gotoNext()) { // retrieve the path and the symbol graph node // nnode = paths_d.getCurr(); curr_node = nnode->getSymbolNode(); // retrieve the list of next nodes from the symbol graph node // SingleLinkedList& next_list = curr_node->getNextNodesList(); // get the corresponding transition scores // SingleLinkedList& lm_scores = curr_node->getLMScoresList(); SingleLinkedList& ac_scores = curr_node->getScoresList(); // loop over all next nodes corresponding to the symbol graph node // lm_scores.gotoFirst(); ac_scores.gotoFirst(); for (bool8 more1 = next_list.gotoFirst(); more1; more1 = next_list.gotoNext()) { // retrieve the next node // next_node = next_list.getCurr(); // retrieve the corresponding language and acoustic model scores // Float* val = (Float*)NULL; if ((val = lm_scores.getCurr()) == (Float*)NULL) { return Error::handle(name(), L"insertNextNode", Error::ARG, __FILE__, __LINE__); } lm_score = (float32)(*val); val = (Float*)NULL; if ((val = ac_scores.getCurr()) == (Float*)NULL) { return Error::handle(name(), L"insertNextNode", Error::ARG, __FILE__, __LINE__); } ac_score = (float32)(*val); // retrieve the corresponding frame index and score // frame_index = next_node->getFrameIndex(); score = nnode->getPathScore() + ac_score + (scale_a * lm_score) + penalty_a; // add this path to the path list only if it falls within the beam // if (score > (path_list_a[frame_index]->max_score_d - beam_a)) { // create the partial path // new_nbest_node = new NBestNode(next_node, nnode, score); // and add it to the appropriate path list // path_list_a[frame_index]->insertPath(new_nbest_node); // set the max score // if (score > path_list_a[frame_index]->max_score_d) { path_list_a[frame_index]->max_score_d = score; } } // move to the next transition // lm_scores.gotoNext(); ac_scores.gotoNext(); } } // exit gracefully // return true; } // method: prune // // arguments: // float32 beam: (input) beam pruning threshold // int32 max_paths: (input) max number of hypothesis // // return: a bool8 indicating status // // this method prunes partial paths // bool8 NBestPath::prune(float32 beam_a, int32 max_paths_a) { // define local variables // NBestNode* node = (NBestNode*)NULL; NBestNode* nnode = (NBestNode*)NULL; float32 beam_threshold = 0.0; // when the list of partial paths is empty we are done // if (paths_d.isEmpty()) { return true; } // determine the beam threshold // beam_threshold = max_score_d - beam_a; // loop over all paths in the partial list // bool8 more_paths = paths_d.gotoFirst(); while (more_paths) { // get current path from the list // nnode = paths_d.getCurr(); if (nnode == (NBestNode*)NULL) { return Error::handle(name(), L"prune", Error::ARG, __FILE__, __LINE__); } // if this node falls below threshold, prune it // if (nnode->getPathScore() < beam_threshold) { // is this the last path in the list? // if (paths_d.isLast()) { more_paths = false; } // remove the node from the list // paths_d.remove(node); // free allocated memory // delete node; node = (NBestNode*)NULL; } else { // move to the next path in the list // more_paths = paths_d.gotoNext(); } } // prune to limit the maximum number of paths in the list // while (paths_d.length() > max_paths_a) { // remove the node from the list // paths_d.removeLast(node); // free allocated memory // delete node; node = (NBestNode*)NULL; } // exit gracefully // return true; }