// file: $isip/class/search/HierarchicalSearch/hsrch_05.cc // version: $Id: hsrch_05.cc 9742 2004-08-20 20:43:15Z may $ // // isip include files // #include "HierarchicalSearch.h" // method: forcedAlignment // // arguments: // String& alignment: (output) forced allignment // Long level: (input) the level to print hypotheses // DoubleLinkedList& trace_path: (input) best hypothesis trace path // bool8 cumulative: (input) whether to output a cumulative score // // return: logical error status // // method to output the forced allignment of the current decoded transcription // bool8 HierarchicalSearch::forcedAlignment(String& alignment_a, Long level_a, DoubleLinkedList& trace_path_a, bool8 cumulative_a) { // declare local variables // Trace* tmp_trace = (Trace*)NULL; SearchNode* prev_node = (SearchNode*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; int32 counter = 0; int32 frame_ind = 0; int32 prev_frame_ind = -1; float32 score = 0.0; float32 prev_score = 0.0; int32 curr_level = 0; String out_str; SearchSymbol sym; // clear the output // alignment_a.clear(); // check the level specification // if ((int32)level_a < 0) { return Error::handle(name(), L"forcedAlignment - invalid level specified", Error::ARG, __FILE__, __LINE__); } // use the best hypothesis trace path to generate the forced allignment // for (bool8 more_traces = trace_path_a.gotoFirst(); more_traces; more_traces = trace_path_a.gotoNext()) { counter++; tmp_trace = trace_path_a.getCurr(); frame_ind = tmp_trace->getFrame(); // get the central vertex from the top of the history stack // GraphVertex* tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_trace->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { return Error::handle(name(), L"forcedAlignment", Error::ARG, __FILE__, __LINE__); } // make sure the vertex is neither the dummy // start nor terminating node // if ((!tmp_vertex->isStart()) && (!tmp_vertex->isTerm())) { tmp_node = tmp_vertex->getItem(); curr_level = tmp_node->getSearchLevel()->getLevelIndex(); if (curr_level == level_a) { tmp_node->getSymbol(sym); score = tmp_trace->getScore(); // generate the output hypothesis // if (counter > 1) { out_str.assign(L"\n"); } else { out_str.assign(L""); } // append previous frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(prev_frame_ind); } else { out_str.concat(prev_frame_ind + 1); } out_str.concat(L"\t"); // append current frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(frame_ind); } else { out_str.concat(frame_ind + 1); } out_str.concat(L"\t"); // append search symbol // out_str.concat(sym); out_str.concat(L"\t"); // append score // out_str.concat(score - prev_score); // append cumulative score if required // if (cumulative_a) { out_str.concat(L"\t"); out_str.concat(score); } // append partial string to the complete hypothesis report // if (level_a == (getNumLevels() - 1)) { alignment_a.concat(out_str); } else { if ((frame_ind != prev_frame_ind) && (frame_ind != 0)) { alignment_a.concat(out_str); } } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } } } // exit gracefully // return true; } // method: generateSymbolGraph // // arguments: // SymbolGraphNode* prev_node: (input) previous node // SymbolGraphNode* curr_node: (input) current node // float32 score: (input) transition score // float32 lm_score: (input) language model score // // return: logical error status // // this method recursively sets up the symbol graph transitions and computes // acoustic and language model scores for each transition // bool8 HierarchicalSearch::generateSymbolGraph(SymbolGraphNode* prev_node_a, SymbolGraphNode* curr_node_a, float32 score_a, float32 lm_score_a) { // declare local variables // Float prev_score; Float prevlm_score; SymbolGraphNode* prev_node = (SymbolGraphNode*)NULL; // error checking // if ((prev_node_a == (SymbolGraphNode*)NULL) || (curr_node_a == (SymbolGraphNode*)NULL)) { return Error::handle(name(), L"generateSymbolGraph", Error::ARG, __FILE__, __LINE__); } // determine the language model score for the forward transition // float32 lm_scale = curr_node_a->getParentGraph()->getScale(); float32 symbol_penalty = curr_node_a->getParentGraph()->getPenalty(); float32 lm_score = lm_score_a / lm_scale; // determine the acoustic model score for the forward transition // float32 ac_score = 0.0; float32 score = curr_node_a->getScore(); if (prev_node_a != symbol_graph_d.getTerm()) { ac_score = score_a - score - (lm_score * lm_scale + symbol_penalty); } if (debug_level_d >= Integral::DETAILED) { String src_str; String dst_str; curr_node_a->getSymbol(src_str); prev_node_a->getSymbol(dst_str); String output(L"\n-> src: "); output.concat(curr_node_a); output.concat(L" ["); output.concat(src_str); output.concat(L"], frame: "); output.concat(curr_node_a->getFrameIndex()); output.concat(L", dst: "); output.concat(prev_node_a); output.concat(L" ["); output.concat(dst_str); output.concat(L"], frame: "); output.concat(prev_node_a->getFrameIndex()); output.concat(L", ac score: "); output.concat(ac_score); output.concat(L", lm score: "); output.concat(lm_score); Console::put(output); } // insert the forward transition in the symbol graph // curr_node_a->insertNextNode(prev_node_a, lm_score, ac_score); // get the list of all previous nodes and scores // SingleLinkedList& prev_list = curr_node_a->getPrevNodesList(); SingleLinkedList& prev_scores = curr_node_a->getPrevScoresList(); SingleLinkedList& prevlm_scores = curr_node_a->getPrevLMScoresList(); // loop over all nodes in the list // bool8 has_more_nodes = prev_list.gotoFirst() & prev_scores.gotoFirst() & prevlm_scores.gotoFirst(); while (has_more_nodes) { // determine the previous node and the path transition score // prev_list.removeFirst(prev_node); prev_score.assign(*(prev_scores.getFirst())); prev_scores.removeFirst(); prevlm_score.assign(*(prevlm_scores.getFirst())); prevlm_scores.removeFirst(); // recursively visit all preceding nodes in the graph // if (!generateSymbolGraph(curr_node_a, prev_node, (float32)prev_score, (float32)prevlm_score)) { return Error::handle(name(), L"generateSymbolGraph", Error::ARG, __FILE__, __LINE__); } // move to the next node in the list // has_more_nodes = prev_list.gotoFirst() & prev_scores.gotoFirst() & prevlm_scores.gotoFirst(); } // exit gracefully // return true; } // method: generateSymbolGraph // // arguments: none // // return: logical error status // // this method sets up the symbol graph transitions and computes acoustic and // language model scores for each transition // bool8 HierarchicalSearch::generateSymbolGraph() { // declare local variables // Float prev_score; Float prevlm_score; SymbolGraphNode* prev_node = (SymbolGraphNode*)NULL; SymbolGraphNode* curr_node = symbol_graph_d.getTerm(); // get the list of all previous nodes and scores // SingleLinkedList& prev_list = curr_node->getPrevNodesList(); SingleLinkedList& prev_scores = curr_node->getPrevScoresList(); SingleLinkedList& prevlm_scores = curr_node->getPrevLMScoresList(); // loop over all nodes in the list // bool8 has_more_nodes = prev_list.gotoFirst() & prev_scores.gotoFirst() & prevlm_scores.gotoFirst(); while (has_more_nodes) { // determine the previous node and the path transition score // prev_list.removeFirst(prev_node); prev_score.assign(*(prev_scores.getFirst())); prev_scores.removeFirst(); prevlm_score.assign(*(prevlm_scores.getFirst())); prevlm_scores.removeFirst(); // recursively visit all preceding nodes in the graph // if (!generateSymbolGraph(curr_node, prev_node, (float32)prev_score, (float32)prevlm_score)) { return Error::handle(name(), L"generateSymbolGraph", Error::ARG, __FILE__, __LINE__); } // move to the next node in the list // has_more_nodes = prev_list.gotoFirst() & prev_scores.gotoFirst() & prevlm_scores.gotoFirst(); } // exit gracefully // return true; } // method: initializeSymbolGraphTrace // // arguments: // float64& score: (output) utterance score // int32& num_frames: (output) total number of frames // // return: logical error status // // this method completes the symbol graph generation for the utterance // bool8 HierarchicalSearch::initializeSymbolGraphTrace(float64& score_a, int32& num_frames_a) { // declare local variables // Trace* tmp_trace = (Trace*)NULL; // move all traces forward in the search space // if (!propagateTraces()) { return false; } // make sure we have at least one valid hypothesis // if (trace_valid_hyps_d.length() < 1) { return false; } // loop over all valid traces in the hypothesis list // trace_valid_hyps_d.gotoFirst(); Trace* best_end_hyp = trace_valid_hyps_d.getCurr(); // find the trace with the best score, i.e., best hypothesis trace // while (true) { if (!trace_valid_hyps_d.gotoNext()) { break; } tmp_trace = trace_valid_hyps_d.getCurr(); if (tmp_trace->getScore() > best_end_hyp->getScore()) { best_end_hyp = tmp_trace; } } // when we are generating a symbol graph // if (best_end_hyp->getSymbolNode() == (SymbolGraphNode*)NULL) { return false; } // set the utterance score // score_a = best_end_hyp->getScore(); // set the total number of frames // num_frames_a = best_end_hyp->getFrame(); // create a transition from the best hypothesis to the term of the // symbol graph // SymbolGraphNode* new_symbol_node = symbol_graph_d.getTerm(); new_symbol_node->setParentGraph(&symbol_graph_d); new_symbol_node->setFrameIndex(num_frames_a); // loop over all valid instances in the hypothesis list // trace_valid_hyps_d.gotoFirst(); while (true) { // retrieve the current trace // tmp_trace = trace_valid_hyps_d.getCurr(); // create a transition from the best hypothesis to the term of the // symbol graph // SymbolGraphNode* old_symbol_node = tmp_trace->getSymbolNode(); float32 path_score = tmp_trace->getScore(); int32 history_paths = getSearchLevel((int32)initial_level_d).getHistoryPaths(); new_symbol_node->insertPrevNode(old_symbol_node, path_score, history_paths, 0.0); if (!trace_valid_hyps_d.gotoNext()) { break; } } // prune the symbol graph - remove all unreferenced nodes // if (!symbol_graph_d.prune()) { return Error::handle(name(), L"finalizeSymbolGraph", Error::ARG, __FILE__, __LINE__); } // determine the symbol graph generation level // int32 level = -1; for (int32 i=0; i < h_digraph_d->length(); i++) { if ((*h_digraph_d)(i).useSymbolGraph()) { level = i; break; } } if (level < 0) { return Error::handle(name(), L"initializeSymbolGraph", Error::ARG, __FILE__, __LINE__); } // set the language model order // symbol_graph_d.setOrder(getSearchLevel(level).getNSymbolOrder()); // set the language model scale // symbol_graph_d.setScale(getSearchLevel(level).getLmScale()); // set the symbol insertion penalty // symbol_graph_d.setPenalty(getSearchLevel(level).getSymbolPenalty()); // exit gracefully // return true; } // method: initializeSymbolGraphInstance // // arguments: // float64& score: (output) utterance score // int32& num_frames: (output) total number of frames // // return: logical error status // // this method completes the symbol graph generation for the utterance // bool8 HierarchicalSearch::initializeSymbolGraphInstance(float64& score_a, int32& num_frames_a) { // declare local variables // Instance* tmp_instance = (Instance*)NULL; // move all traces forward in the search space // if (!propagateLexInstances()) { return false; } // make sure we have at least one valid hypothesis // if (instance_valid_hyps_d.length() < 1) { return false; } // loop over all valid instances in the hypothesis list // instance_valid_hyps_d.gotoFirst(); Instance* best_end_hyp = instance_valid_hyps_d.getCurr(); // find the instance with the best score, i.e., best hypothesis trace // while (true) { if (!instance_valid_hyps_d.gotoNext()) { break; } tmp_instance = instance_valid_hyps_d.getCurr(); if (tmp_instance->getScore() > best_end_hyp->getScore()) { best_end_hyp = tmp_instance; } } // when we are generating a symbol graph // if (best_end_hyp->getSymbolNode() == (SymbolGraphNode*)NULL) { return false; } // set the utterance score // score_a = best_end_hyp->getScore(); // set the total number of frames // num_frames_a = best_end_hyp->getFrame(); // loop over all valid instances in the hypothesis list // instance_valid_hyps_d.gotoFirst(); SymbolGraphNode* new_symbol_node = symbol_graph_d.getTerm(); new_symbol_node->setParentGraph(&symbol_graph_d); new_symbol_node->setFrameIndex(num_frames_a); while (true) { // retrieve the current instance // tmp_instance = instance_valid_hyps_d.getCurr(); // create a transition from the best hypothesis to the term of the // symbol graph // SymbolGraphNode* old_symbol_node = tmp_instance->getSymbolNode(); float32 path_score = tmp_instance->getScore(); int32 history_paths = getSearchLevel((int32)initial_level_d).getHistoryPaths(); new_symbol_node->insertPrevNode(old_symbol_node, path_score, history_paths, 0.0); if (!instance_valid_hyps_d.gotoNext()) { break; } } // prune the symbol graph - remove all unreferenced nodes // if (!symbol_graph_d.prune()) { return Error::handle(name(), L"finalizeSymbolGraph", Error::ARG, __FILE__, __LINE__); } // determine the symbol graph generation level // int32 level = -1; for (int32 i=0; i < h_digraph_d->length(); i++) { if ((*h_digraph_d)(i).useSymbolGraph()) { level = i; break; } } if (level < 0) { return Error::handle(name(), L"initializeSymbolGraph", Error::ARG, __FILE__, __LINE__); } // set the language model order // symbol_graph_d.setOrder(getSearchLevel(level).getNSymbolOrder()); // set the language model scale // symbol_graph_d.setScale(getSearchLevel(level).getLmScale()); // set the symbol insertion penalty // symbol_graph_d.setPenalty(getSearchLevel(level).getSymbolPenalty()); // exit gracefully // return true; } // method: getHypotheses // // arguments: // String& output_hyp: (output) the current search hypotheses // int32 level: (input) the level to print hypotheses from // float64& total_score: (output) the hypothesis total score // int32& num_frames: (output) frame index of the last trace // DoubleLinkedList& trace_path: (output) best hypothesis trace path // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 HierarchicalSearch::getHypotheses(String& output_hyp_a, int32 level_a, float64& total_score_a, int32& num_frames_a, DoubleLinkedList& trace_path_a) { // declare local variables // Trace* tmp_trace = (Trace*)NULL; SearchNode* prev_node = (SearchNode*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; BiGraphVertex* vertex = (BiGraphVertex*)NULL; int32 counter = 0; int32 curr_level = 0; int32 frame_ind = 0; int32 prev_frame_ind = -1; int32 back_count = 0; float32 score = 0.0; float32 prev_score = 0.0; int32 symbol_id = 0; String out_str; SearchSymbol sym; // clear the output and set the allocation mode for the trace path // output_hyp_a.clear(); trace_path_a.clear(); trace_path_a.setAllocationMode(DstrBase::USER); // move all traces forward in the search space // if (!propagateTraces()) { return false; } // make sure we have at least one valid hypothesis // if (trace_valid_hyps_d.length() < 1) { return false; } if (search_mode_d == TRAIN) { // loop over all valid hypothesis // for (bool8 more = trace_valid_hyps_d.gotoFirst(); more; more = trace_valid_hyps_d.gotoNext()) { // retrieve the vertex corresponding to the trace // vertex = trace_valid_hyps_d.getCurr()->getReference(); if (vertex == (BiGraphVertex*)NULL) { return Error::handle(name(), L"getHypotheses - cannot find the valid hypothesis in the trellis", Error::ARG, __FILE__, __LINE__); } // connect the current vertex to the terminal node // trellis_d.insertArc(vertex, trellis_d.getTerm(), false, 0); } } // loop over all valid traces in the hypothesis list // trace_valid_hyps_d.gotoFirst(); Trace* best_end_hyp = trace_valid_hyps_d.getCurr(); // find the trace with the best score, i.e., best hypothesis trace // while (true) { if (!trace_valid_hyps_d.gotoNext()) { break; } tmp_trace = trace_valid_hyps_d.getCurr(); if (tmp_trace->getScore() > best_end_hyp->getScore()) { best_end_hyp = tmp_trace; } } // backtrack from the best hypothesis trace and generate the trace path // for (tmp_trace = best_end_hyp; tmp_trace != (Trace*)NULL; tmp_trace = tmp_trace->getBackPointer()) { trace_path_a.insertFirst(tmp_trace); back_count++; } // use the best hypothesis trace path to generate the hypothesis string // for (bool8 more_traces = trace_path_a.gotoFirst(); more_traces; more_traces = trace_path_a.gotoNext()) { counter++; tmp_trace = trace_path_a.getCurr(); frame_ind = tmp_trace->getFrame(); // get the central vertex from the top of the history stack // GraphVertex* tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_trace->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { return Error::handle(name(), L"getHypotheses - NULL VERTEX", Error::ARG, __FILE__, __LINE__); } // make sure the vertex is neither the dummy // start nor terminating node // if ((!tmp_vertex->isStart()) && (!tmp_vertex->isTerm())) { tmp_node = tmp_vertex->getItem(); curr_level = tmp_node->getSearchLevel()->getLevelIndex(); if ((level_a < 0) && (curr_level == (int32)initial_level_d)) { tmp_node->getSymbol(sym); score = tmp_trace->getScore(); symbol_id = tmp_node->getSymbolId(); // generate the output hypothesis containing only search symbols // if (!getSearchLevel(curr_level).isExcludeSymbol(symbol_id)) { out_str.assign(sym); out_str.concat(L" "); } else { out_str.assign(L""); } // append partial string to the complete hypothesis report // if ((frame_ind != prev_frame_ind) && (frame_ind != 0)) { output_hyp_a.concat(out_str); } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } if ((level_a >= 0) && (curr_level == level_a)) { String context; tmp_trace->getSymbol()->print(context); score = tmp_trace->getScore(); sym.assign(context); // generate the output hypothesis // if (counter > 1) { out_str.assign(L"\n"); } else { out_str.assign(L""); } // append previous frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(prev_frame_ind); } else { out_str.concat(prev_frame_ind + 1); } out_str.concat(L"\t"); // append current frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(frame_ind); } else { out_str.concat(frame_ind + 1); } out_str.concat(L"\t"); // append search symbol // out_str.concat(sym); out_str.concat(L"\t\t"); // append score // out_str.concat(score - prev_score); // append partial string to the complete hypothesis report // if (level_a == (getNumLevels() - 1)) { output_hyp_a.concat(out_str); } else { if ((frame_ind != prev_frame_ind) && (frame_ind != 0)) { output_hyp_a.concat(out_str); } } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } } } total_score_a = score; num_frames_a = frame_ind; // exit gracefully // return true; } // method: printNewPath // // arguments: // Trace* new_trace: (input) the endpoint of the new arc // Trace* old_trace: (input) the start point of the new arc // // return: logical error status // // print an arc created in the hypothesis space // bool8 HierarchicalSearch::printNewPath(Trace* new_trace_a, Trace* old_trace_a) { SearchSymbol start_sym; SearchSymbol end_sym; float32 old_score = 0.0; float32 new_score = 0.0; int32 old_frame = -1; int32 new_frame = -1; if (old_trace_a != (Trace*)NULL) { GraphVertex* old_vertex = old_trace_a->getSymbol()->getCentralVertex(); old_frame = old_trace_a->getFrame(); if (old_vertex->isStart()) { start_sym.assign(L"_START_"); } else if (old_vertex->isTerm()) { start_sym.assign(L"_TERM_"); } else { old_trace_a->getSymbol()->print(start_sym); } old_score = old_trace_a->getScore(); } if (new_trace_a != (Trace*)NULL) { GraphVertex* new_vertex = new_trace_a->getSymbol()->getCentralVertex(); new_frame = new_trace_a->getFrame(); if (new_vertex->isStart()) { end_sym.assign(L"_START_"); } else if (new_vertex->isTerm()) { end_sym.assign(L"_TERM_"); } else { new_trace_a->getSymbol()->print(end_sym); } new_score = new_trace_a->getScore(); } String val; String out(L"\n-> trace: "); out.concat(new_trace_a); out.concat(L", backpointer: "); out.concat(old_trace_a); out.concat(L"\n ["); out.concat(start_sym); out.concat(L"], frame: "); val.assign((int32)old_frame); out.concat(val); out.concat(L", score: "); out.concat(old_score); out.concat(L" -> ["); out.concat(end_sym); out.concat(L"], frame: "); val.assign((int32)new_frame); out.concat(val); out.concat(L", score: "); out.concat(new_score); Console::put(out); return true; } // method: printDeletedPath // // arguments: // Trace* new_trace: (input) the endpoint of the new arc // Trace* old_trace: (input) the start point of the new arc // // return: logical error status // // print an arc created in the hypothesis space // bool8 HierarchicalSearch::printDeletedPath(Trace* new_trace_a, Trace* old_trace_a) { SearchSymbol start_sym; SearchSymbol end_sym; int32 old_frame = -1; int32 new_frame = -1; if (old_trace_a != (Trace*)NULL) { GraphVertex* old_vertex = old_trace_a->getSymbol()->getCentralVertex(); old_frame = old_trace_a->getFrame(); if (old_vertex->isStart()) { start_sym.assign(L"_START_"); } else if (old_vertex->isTerm()) { start_sym.assign(L"_TERM_"); } else { old_trace_a->getSymbol()->print(start_sym); } } if (new_trace_a != (Trace*)NULL) { GraphVertex* new_vertex = new_trace_a->getSymbol()->getCentralVertex(); new_frame = new_trace_a->getFrame(); if (new_vertex->isStart()) { end_sym.assign(L"_START_"); } else if (new_vertex->isTerm()) { end_sym.assign(L"_TERM_"); } else { new_trace_a->getSymbol()->print(end_sym); } } String val; String out(L"-> deleted trace: "); out.concat(new_trace_a); out.concat(L", backpointer: "); out.concat(old_trace_a); out.concat(L"\n ["); out.concat(start_sym); out.concat(L"], frame: "); val.assign((int32)old_frame); out.concat(val); out.concat(L" -> "); out.concat(end_sym); out.concat(L"], frame: "); val.assign((int32)new_frame); out.concat(val); Console::put(out); return true; } // method: getHypotheses // // arguments: // String& output_hyp: (output) the current search hypotheses // int32 level: (input) the level to print hypotheses from // float64& total_score: (output) the hypothesis total score // int32& num_frames: (output) frame index of the last instance // DoubleLinkedList& instance_path: (output) best hypothesis instance path // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 HierarchicalSearch::getHypotheses(String& output_hyp_a, int32 level_a, float64& total_score_a, int32& num_frames_a, DoubleLinkedList& instance_path_a) { // declare local variables // Instance* tmp_instance = (Instance*)NULL; SearchNode* prev_node = (SearchNode*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; BiGraphVertex* vertex = (BiGraphVertex*)NULL; int32 counter = 0; int32 curr_level = 0; int32 frame_ind = 0; int32 prev_frame_ind = -1; int32 back_count = 0; float32 score = 0.0; float32 prev_score = 0.0; int32 symbol_id = 0; String out_str; SearchSymbol sym; // clear the output and set the allocation mode for the instance path // output_hyp_a.clear(); instance_path_a.clear(); instance_path_a.setAllocationMode(DstrBase::USER); // move all instances forward in the search space // if (!propagateInstances()) { return false; } // make sure we have at least one valid hypothesis // if (instance_valid_hyps_d.length() < 1) { return false; } if (search_mode_d == TRAIN) { // loop over all valid hypothesis and connect them to the trellis term // for (bool8 more = instance_valid_hyps_d.gotoFirst(); more; more = instance_valid_hyps_d.gotoNext()) { vertex = instance_valid_hyps_d.getCurr()->getReference(); if (vertex == (BiGraphVertex*)NULL) { return Error::handle(name(), L"getHypotheses - cannot find the valid hypothesis in the trellis", Error::ARG, __FILE__, __LINE__); } trellis_d.insertArc(vertex, trellis_d.getTerm(), false, 0); } } // loop over all valid instances in the hypothesis list // instance_valid_hyps_d.gotoFirst(); Instance* best_end_hyp = instance_valid_hyps_d.getCurr(); // find the instance with the best score, i.e., best hypothesis instance // while (true) { if (!instance_valid_hyps_d.gotoNext()) { break; } tmp_instance = instance_valid_hyps_d.getCurr(); if (tmp_instance->getScore() > best_end_hyp->getScore()) { best_end_hyp = tmp_instance; } } // backtrack from the best hypothesis instance and generate the instance path // for (tmp_instance = best_end_hyp; tmp_instance != (Instance*)NULL; tmp_instance = tmp_instance->getBackPointer()) { instance_path_a.insertFirst(tmp_instance); back_count++; } // use the best hypothesis instance path to generate the hypothesis string // for (bool8 more_instances = instance_path_a.gotoFirst(); more_instances; more_instances = instance_path_a.gotoNext()) { counter++; tmp_instance = instance_path_a.getCurr(); frame_ind = tmp_instance->getFrame(); // get the central vertex from the top of the history stack // GraphVertex* tmp_vertex = (GraphVertex*)NULL; tmp_vertex = tmp_instance->getSymbol()->getCentralVertex(); // check for a NULL vertex // if (tmp_vertex == (GraphVertex*)NULL) { return Error::handle(name(), L"getHypotheses - NULL VERTEX", Error::ARG, __FILE__, __LINE__); } // make sure the vertex is neither the dummy // start nor terminating node // if ((!tmp_vertex->isStart()) && (!tmp_vertex->isTerm())) { tmp_node = tmp_vertex->getItem(); curr_level = tmp_node->getSearchLevel()->getLevelIndex(); if ((level_a < 0) && (curr_level == (int32)initial_level_d)) { tmp_node->getSymbol(sym); score = tmp_instance->getScore(); symbol_id = tmp_node->getSymbolId(); // generate the output hypothesis containing only search symbols // if (!getSearchLevel(curr_level).isExcludeSymbol(symbol_id)) { out_str.assign(sym); out_str.concat(L" "); } else { out_str.assign(L""); } // append partial string to the complete hypothesis report // if ((frame_ind != prev_frame_ind) && (frame_ind != 0)) { output_hyp_a.concat(out_str); } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } if ((level_a >= 0) && (curr_level == level_a)) { String context; tmp_instance->getSymbol()->print(context); score = tmp_instance->getScore(); sym.assign(context); // generate the output hypothesis // if (counter > 1) { out_str.assign(L"\n"); } else { out_str.assign(L""); } // append previous frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(prev_frame_ind); } else { out_str.concat(prev_frame_ind + 1); } out_str.concat(L"\t"); // append current frame index // if (level_a != (getNumLevels() - 1)) { out_str.concat(frame_ind); } else { out_str.concat(frame_ind + 1); } out_str.concat(L"\t"); // append search symbol // out_str.concat(sym); out_str.concat(L"\t\t"); // append score // out_str.concat(score - prev_score); // append partial string to the complete hypothesis report // if (level_a == (getNumLevels() - 1)) { output_hyp_a.concat(out_str); } else { if ((frame_ind != prev_frame_ind) && (frame_ind != 0)) { output_hyp_a.concat(out_str); } } prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } } } total_score_a = score; num_frames_a = frame_ind; // exit gracefully // return true; } // method: printNewPath // // arguments: // Instance* new_instance: (input) newly created instance // Instance* old_instance: (input) previous instance (backpointer) // // return: logical error status // // prints a transition generated in the hypothesis space // bool8 HierarchicalSearch::printNewPath(Instance* new_instance_a, Instance* old_instance_a) { SearchSymbol start_sym; SearchSymbol end_sym; float32 old_score = 0.0; float32 new_score = 0.0; int32 old_frame = -1; int32 new_frame = -1; if (old_instance_a != (Instance*)NULL) { GraphVertex* old_vertex = old_instance_a->getSymbol()->getCentralVertex(); old_frame = old_instance_a->getFrame(); if (old_vertex->isStart()) { start_sym.assign(L"_START_"); } else if (old_vertex->isTerm()) { start_sym.assign(L"_TERM_"); } else { old_instance_a->getSymbol()->print(start_sym); } old_score = old_instance_a->getScore(); } if (new_instance_a != (Instance*)NULL) { GraphVertex* new_vertex = new_instance_a->getSymbol()->getCentralVertex(); new_frame = new_instance_a->getFrame(); if (new_vertex->isStart()) { end_sym.assign(L"_START_"); } else if (new_vertex->isTerm()) { end_sym.assign(L"_TERM_"); } else { new_instance_a->getSymbol()->print(end_sym); } new_score = new_instance_a->getScore(); } String val; String output(L"\n-> instance: "); output.concat(new_instance_a); output.concat(L", backpointer: "); output.concat(old_instance_a); output.concat(L"\n ["); output.concat(start_sym); output.concat(L"], frame: "); val.assign((int32)old_frame); output.concat(val); output.concat(L", score: "); output.concat(old_score); output.concat(L" -> ["); output.concat(end_sym); output.concat(L"], frame: "); val.assign((int32)new_frame); output.concat(val); output.concat(L", score: "); output.concat(new_score); Console::put(output); return true; } // method: printDeletedPath // // arguments: // Instance* new_instance: (input) the endpoint of the new arc // Instance* old_instance: (input) the start point of the new arc // // return: logical error status // // print an arc created in the hypothesis space // bool8 HierarchicalSearch::printDeletedPath(Instance* new_instance_a, Instance* old_instance_a) { SearchSymbol start_sym; SearchSymbol end_sym; int32 old_frame = -1; int32 new_frame = -1; if (old_instance_a != (Instance*)NULL) { GraphVertex* old_vertex = old_instance_a->getSymbol()->getCentralVertex(); old_frame = old_instance_a->getFrame(); if (old_vertex->isStart()) { start_sym.assign(L"_START_"); } else if (old_vertex->isTerm()) { start_sym.assign(L"_TERM_"); } else { old_instance_a->getSymbol()->print(start_sym); } } if (new_instance_a != (Instance*)NULL) { GraphVertex* new_vertex = new_instance_a->getSymbol()->getCentralVertex(); new_frame = new_instance_a->getFrame(); if (new_vertex->isStart()) { end_sym.assign(L"_START_"); } else if (new_vertex->isTerm()) { end_sym.assign(L"_TERM_"); } else { new_instance_a->getSymbol()->print(end_sym); } } String val; String output(L"\n-> deleted instance: "); output.concat(new_instance_a); output.concat(L", backpointer: "); output.concat(old_instance_a); output.concat(L"\n ["); output.concat(start_sym); output.concat(L"], frame: "); val.assign((int32)old_frame); output.concat(val); output.concat(L" -> ["); output.concat(end_sym); output.concat(L"], frame: "); val.assign((int32)new_frame); output.concat(val); Console::put(output); return true; }