// file: $isip/class/search/StackSearch/ssrch_05.cc // version: $Id: ssrch_05.cc 9173 2003-05-30 02:02:08Z jelinek $ // // isip include files // #include "StackSearch.h" // 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 // String* word_hyp: (output) word level hypothesis // // return: logical error status // // build a graph representing the hypotheses and return it // bool8 StackSearch::getHypotheses(String& output_hyp_a, int32 level_a, float64& total_score_a, int32& num_frames_a, DoubleLinkedList& trace_path_a, String* word_hyp_a) { if (debug_level_d >= Integral::ALL) { Console::put(L"\nGetting the hypotheses ...\n\n"); } // declare local variables // Trace* tmp_trace = (Trace*)NULL; SearchNode* prev_node = (SearchNode*)NULL; SearchNode* tmp_node = (SearchNode*)NULL; int32 counter = 0; int32 curr_level = 0; int32 frame_ind = 0; int32 wframe_ind = 0; int32 prev_frame_ind = -1; int32 wprev_frame_ind = -1; int32 back_count = 0; float32 score = 0.0; float32 prev_score = 0.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 (stack_level_d < (int32)1) { if (!((decoding_mode_d == GLOBAL_STACK) && (stack_level_d == (int32)0))) { if (!propagateTraces()) { // cleanup after the utterance // // clear the stacks // for (int32 i = 0; i < stacks_d.length(); i++) { stacks_d(i).clear(); } if (decoding_mode_d == GLOBAL_STACK) { if (debug_level_d >= Integral::BRIEF) { Console::put(L"going to clear glob stack, capacity: "); String cap = global_stack_d.getCapacity(); Console::put(cap); } while (!global_stack_d.isEmpty()) { Hypothesis hyp; global_stack_d.pop(&hyp); Trace* tr = hyp.getTrace(); Trace::deleteTrace(tr, true, true); } } // clean state traces // DoubleLinkedList state_traces(DstrBase::USER); getTraces(state_traces, getNumLevels() - 1); Trace* curr_trace = NULL; while (state_traces.removeFirst(curr_trace)) { Trace::deleteTrace(curr_trace, true); } // clear valid hypotheses // clearValidHypsTrace(); // exit ungracefully // return false; } } } // make sure we have at least one valid hypothesis // if (valid_hyps_d.length() < 1) { // output the debugging information // if (debug_level_d >= Integral::ALL) { Console::put(L"no valid hypotheses found, cleaning"); } // cleanup after the utterance // // clear the stacks // for (int32 i = 0; i < stacks_d.length(); i++) { stacks_d(i).clear(); } // clean state traces // DoubleLinkedList state_traces(DstrBase::USER); getTraces(state_traces, getNumLevels() - 1); Trace* curr_trace = NULL; while (state_traces.removeFirst(curr_trace)) { Trace::deleteTrace(curr_trace, true); } // clear valid hypotheses // clearValidHypsTrace(); // exit ungracefully // return false; } // pick up the best valid hypothesis // Trace* best_end_hyp = valid_hyps_d.pop(); if (debug_level_d >= Integral::ALL) { String out(L"Best hypothesis: "); out.concat(best_end_hyp); Console::put(out); } // 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(); wframe_ind = frame_ind; // get the central vertex // GraphVertex* 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 == 0)) { tmp_node->getSymbol(sym); score = tmp_trace->getScore(); int32 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); } } if ((curr_level == 0) && (word_hyp_a != NULL)) { SearchSymbol ss; tmp_node->getSymbol(ss); // generate the output hypothesis containing only search symbols // String out; if (sym.ne(L"!SENT_START") && sym.ne(L"!SENT_END")) { out.assign(ss); out.concat(L" "); } else { out.assign(L""); } // append partial string to the complete hypothesis report // if ((wframe_ind != wprev_frame_ind) && (wframe_ind != 0)) { word_hyp_a->concat(out); } wprev_frame_ind = wframe_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); } } } if (((level_a < 0) && (curr_level == 0)) || ((level_a >= 0) && (curr_level == level_a))) { prev_node = tmp_node; prev_score = score; prev_frame_ind = frame_ind; } } } if ((evaluation_mode_d == SEGMENT_EVAL) && (level_a == getNumLevels() - 1)) { score = best_end_hyp->getScore(); output_hyp_a.concat(L"\n\t\t\t\t"); output_hyp_a.concat(score - prev_score); } total_score_a = score; num_frames_a = frame_ind; Trace::deleteTrace(best_end_hyp, true, true); // cleanup after the utterance // // clear the stacks // for (int32 i = 0; i < stacks_d.length(); i++) { stacks_d(i).clear(); } if (decoding_mode_d == GLOBAL_STACK) { if (debug_level_d >= Integral::BRIEF) { Console::put(L"going to clear glob stack, capacity: "); String cap = global_stack_d.getCapacity(); Console::put(cap); } while (!global_stack_d.isEmpty()) { Hypothesis hyp; global_stack_d.pop(&hyp); Trace* tr = hyp.getTrace(); Trace::deleteTrace(tr, true, true); } } // clean state traces // DoubleLinkedList state_traces(DstrBase::USER); getTraces(state_traces, getNumLevels() - 1); Trace* curr_trace = NULL; while (state_traces.removeFirst(curr_trace)) { Trace::deleteTrace(curr_trace, true); } // clear valid hypotheses // clearValidHypsTrace(); // output statistics // if (debug_level_d >= Integral::BRIEF) { String out(L"\nFrame: "); out.concat(L" Traces generated: "); out.concat(L" Vit. pruned: "); out.concat(L" beam pruned: "); out.concat(L" evaluated: "); out.concat(L" avoided eval: "); Console::put(out); int32 num_traces_gen = 0; int32 num_traces_vit_prun = 0; int32 num_traces_beam_prun = 0; int32 num_eval = 0; int32 num_avoided_eval = 0; for (int32 i = 0; i < num_frames_d; i++) { out.assign(i); out.concat(L" "); out.concat(num_traces_gen_d(i)); num_traces_gen += num_traces_gen_d(i); out.concat(L" "); out.concat(num_traces_vit_prun_d(i)); num_traces_vit_prun += num_traces_vit_prun_d(i); out.concat(L" "); out.concat(num_traces_beam_prun_d(i)); num_traces_beam_prun += num_traces_beam_prun_d(i); out.concat(L" "); out.concat(num_eval_d(i)); num_eval += num_eval_d(i); out.concat(L" "); out.concat(num_avoided_eval_d(i)); num_avoided_eval += num_avoided_eval_d(i); Console::put(out); } out.assign(L"Total: "); out.concat(num_traces_gen); out.concat(L" "); out.concat(num_traces_vit_prun); out.concat(L" "); out.concat(num_traces_beam_prun); out.concat(L" "); out.concat(num_eval); out.concat(L" "); out.concat(num_avoided_eval); out.concat(L" num stat mod: "); out.concat(stat_model_mapping_d.length()); Console::put(out); } // 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 StackSearch::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) { SearchNode* old_node = old_trace_a->getSymbol()->getCentralVertex()->getItem(); old_frame = old_trace_a->getFrame(); if ( old_node == &DiGraph::START_OBJ) { start_sym.assign(L"_START_"); } else if (old_node == &DiGraph::TERM_OBJ) { start_sym.assign(L"_TERM_"); } else { old_node->getSymbol(start_sym); } old_score = old_trace_a->getScore(); } if (new_trace_a != (Trace*)NULL) { SearchNode* new_node = new_trace_a->getSymbol()->getCentralVertex()->getItem(); new_frame = new_trace_a->getFrame(); if (new_node == &DiGraph::START_OBJ) { end_sym.assign(L"_START_"); } else if (new_node == &DiGraph::TERM_OBJ) { end_sym.assign(L"_TERM_"); } else { new_node->getSymbol(end_sym); } new_score = new_trace_a->getScore(); } String out(L" oTR "); out.concat(old_trace_a); out.concat(L" ["); out.concat(start_sym); out.concat(L"] -> ["); out.concat(end_sym); out.concat(L"] nTR "); out.concat(new_trace_a); out.concat(L" oSC: "); out.concat(old_score); out.concat(L" -> nSC: "); out.concat(new_score); out.concat(L" FR "); out.concat(new_frame); 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 StackSearch::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) { SearchNode* old_node = old_trace_a->getSymbol()->getCentralVertex()->getItem(); old_frame = old_trace_a->getFrame(); if ( old_node == &DiGraph::START_OBJ) { start_sym.assign(L"_START_"); } else if (old_node == &DiGraph::TERM_OBJ) { start_sym.assign(L"_TERM_"); } else { old_node->getSymbol(start_sym); } } if (new_trace_a != (Trace*)NULL) { SearchNode* new_node = new_trace_a->getSymbol()->getCentralVertex()->getItem(); new_frame = new_trace_a->getFrame(); if (new_node == &DiGraph::START_OBJ) { end_sym.assign(L"_START_"); } else if (new_node == &DiGraph::TERM_OBJ) { end_sym.assign(L"_TERM_"); } else { new_node->getSymbol(end_sym); } } String out(L"deleted trace "); out.concat(new_trace_a); out.concat(L" generated from ["); out.concat(start_sym); out.concat(L"] in frame "); String val; val.assign((int32)old_frame); out.concat(val); out.concat(L" to ["); out.concat(end_sym); out.concat(L"] in frame "); val.assign((int32)new_frame); out.concat(val); Console::put(out); return true; }