// file: $isip/class/search/SearchNode/snod_06.cc // version: $Id: snod_06.cc 9347 2003-11-26 20:46:15Z alphonso $ // // isip include files // #include "SearchNode.h" #include #include // method: addTrace // // arguments: // Trace* trace: (input) the trace to add to the trace list. we do Viterbi // pruning at this point // int32 timestamp: (input) the timestamp for the incoming trace // Trace* ptr: (input) pointer to existing trace with the same history // // return: a bool8 indicating status // // this method adds the trace to the trace list if it is the highest scoring // trace at that point // bool8 SearchNode::addTrace(Trace* trace_a, int32 timestamp_a, Trace*& ptr_a) { // declare local variables // bool8 status = true; if (this == &DiGraph::TERM_OBJ || this == &DiGraph::START_OBJ || isDummyNode()) { return status; } // output the debugging information // if (debug_level_d == Integral::ALL) { String output(L"attempting to adding trace: "); output.concat(trace_a); output.concat(L" to snode ["); SearchSymbol symbol; getSymbol(symbol); output.concat(symbol); output.concat(L"] old timestamp:"); output.concat(timestamp_d); output.concat(L" new timestamp:"); output.concat(timestamp_a); output.concat(L" num traces:"); output.concat(traces_d.length()); Console::put(output); } // check the timestamp // if (timestamp_a != timestamp_d) { traces_d.clear(); score_d = Trace::INACTIVE_SCORE; timestamp_d = timestamp_a; } // do Viterbi pruning - at this time, we only handle one-best Viterbi // if (trace_a->getTraceMode() == Trace::TRAIN) { status = addWithBaumWelch(trace_a, ptr_a); } else { status = addWithViterbi(trace_a, ptr_a); } return status; } // method: mergeTrace // // arguments: // Trace* trace: (input) the trace to add to the trace list. we do Viterbi // pruning at this point // int32 timestamp: (input) the timestamp for the incoming trace // Trace* ptr: (input) pointer to existing trace with the same history // int32 nsymbol_index: (input) nsymbol index // int32 nsymbol_order: (input) nsymbol order // // return: a bool8 indicating status // // this method adds the trace to the trace list if it is the highest scoring // trace at that point // bool8 SearchNode::mergeTrace(Trace* trace_a, int32 timestamp_a, Trace*& ptr_a, int32 nsymbol_index_a, int32 nsymbol_order_a) { if (this == &DiGraph::TERM_OBJ || this == &DiGraph::START_OBJ || isDummyNode()) { return true; } // output the debugging information // if (debug_level_d == Integral::ALL) { String output(L"attempting to adding trace: "); output.concat(trace_a); output.concat(L" to snode ["); SearchSymbol symbol; getSymbol(symbol); output.concat(symbol); output.concat(L"] old timestamp:"); output.concat(timestamp_d); output.concat(L" new timestamp:"); output.concat(timestamp_a); output.concat(L" num traces:"); output.concat(traces_d.length()); Console::put(output); } // check the timestamp // if (timestamp_a != timestamp_d) { traces_d.clear(); score_d = Trace::INACTIVE_SCORE; timestamp_d = timestamp_a; } // if there are no traces here, then just add this one // if (traces_d.isEmpty()) { traces_d.insertFirst(trace_a); return true; } // a flag showing that if need to add a trace // bool8 add_flag = false; // see if any other trace with the same history exists at this point // right now we loop over all traces at this point and compare histories // for (bool8 more_traces = traces_d.gotoFirst(); more_traces; more_traces = traces_d.gotoNext()) { Trace* curr_trace = traces_d.getCurr(); if (trace_a == curr_trace) { return Error::handle(name(), L"mergeTrace", Error::ARG, __FILE__, __LINE__); } // make sure the timestamps match even before we compare them // bool8 are_same = true; // compare the traces // if ((curr_trace->getFrame() != trace_a->getFrame()) || (curr_trace->getSymbol() != trace_a->getSymbol()) || (curr_trace->getHistory() != trace_a->getHistory())) { are_same = false; } // compare the nsymbols // Context** context1 = trace_a->getNSymbol(); Context** context2 = curr_trace->getNSymbol(); for (int32 index=1; index < nsymbol_order_a; index++) { if ((*context1[nsymbol_index_a])(-index) != (*context2[nsymbol_index_a])(-index)) { are_same = false; break; } } if (are_same) { add_flag = true; // set the pointer of the trace that already exists // ptr_a = curr_trace; if (trace_a->getScore() > curr_trace->getScore()) { traces_d.remove(curr_trace); // delete the bad trace if possible // if (curr_trace->getRefCount() < 1) { curr_trace->setActive(false); } // add the new trace // traces_d.insertFirst(trace_a); return true; } else { trace_a->setActive(false); return false; } } } // no trace is the same as the one to be added, add this one // if (!add_flag) { traces_d.insert(trace_a); } // exit gracefully // return true; } // method: mergeInstance // // arguments: // Instance* instance: (input) the instance to add to the instance list // int32 timestamp: (input) the timestamp for the incoming instance // Instance* ptr: (input) pointer to existing instance with the same history // int32 nsymbol_index: (input) nsymbol index // int32 nsymbol_order: (input) nsymbol order // // return: a bool8 indicating status // // this method adds the instance to the instance list if it is the highest // scoring instance at that point // bool8 SearchNode::mergeInstance(Instance* instance_a, int32 timestamp_a, Instance*& ptr_a, int32 nsymbol_index_a, int32 nsymbol_order_a) { if (this == &DiGraph::TERM_OBJ || this == &DiGraph::START_OBJ || isDummyNode()) { return true; } // output the debugging information // if (debug_level_d == Integral::ALL) { String output(L"attempting to adding instance: "); output.concat(instance_a); output.concat(L" to snode ["); SearchSymbol symbol; getSymbol(symbol); output.concat(symbol); output.concat(L"] old timestamp:"); output.concat(timestamp_d); output.concat(L" new timestamp:"); output.concat(timestamp_a); output.concat(L" num instances:"); output.concat(instances_d.length()); Console::put(output); } // check the timestamp // if (timestamp_a != timestamp_d) { instances_d.clear(); score_d = Instance::INACTIVE_SCORE; timestamp_d = timestamp_a; } // if there are no instances here, then just add this one // if (instances_d.isEmpty()) { instances_d.insertFirst(instance_a); return true; } // a flag showing that if need to add a instance // bool8 add_flag = false; // see if any other instance with the same history exists at this point // right now we loop over all instances at this point and compare histories // for (bool8 more_instances = instances_d.gotoFirst(); more_instances; more_instances = instances_d.gotoNext()) { Instance* curr_instance = instances_d.getCurr(); if (instance_a == curr_instance) { return Error::handle(name(), L"mergeInstance", Error::ARG, __FILE__, __LINE__); } // make sure the timestamps match even before we compare them // bool8 are_same = true; // compare the instances // if ((curr_instance->getFrame() != instance_a->getFrame()) || (curr_instance->getSymbol() != instance_a->getSymbol()) || (curr_instance->getHistory() != instance_a->getHistory()) || (curr_instance->getSymbolStack() != instance_a->getSymbolStack())) { are_same = false; } // compare the nsymbols // Context** context1 = instance_a->getNSymbol(); Context** context2 = curr_instance->getNSymbol(); for (int32 index=1; index < nsymbol_order_a; index++) { if ((*context1[nsymbol_index_a])(-index) != (*context2[nsymbol_index_a])(-index)) { are_same = false; break; } } if (are_same) { add_flag = true; // set the pointer of the instance that already exists // ptr_a = curr_instance; if (instance_a->getScore() > curr_instance->getScore()) { instances_d.remove(curr_instance); // delete the bad instance if possible // if (curr_instance->getRefCount() < 1) { curr_instance->setActive(false); } // add the new instance // instances_d.insertFirst(instance_a); return true; } else { instance_a->setActive(false); return false; } } } // no instance is the same as the one to be added, add this one // if (!add_flag) { instances_d.insert(instance_a); } // exit gracefully // return true; } // method: addWithViterbi // // arguments: // Trace* trace: (input) the trace to add to the trace list. we do Viterbi // pruning at this point // Trace* ptr: (input) pointer to the existing trace with the same history // // return: a bool8 indicating status // // this method adds the trace to the trace list if it is the highest scoring // trace at that point // bool8 SearchNode::addWithViterbi(Trace* trace_a, Trace*& ptr_a) { // if there are no traces here, then just add this one // if (traces_d.isEmpty()) { traces_d.insertFirst(trace_a); return true; } // a flag showing that if need to add a trace // bool8 add_flag = false; ulong input_trace_frame_index = trace_a->getFrame(); // see if any other trace with the same history exists at this point // right now we loop over all traces at this point and compare histories // for (bool8 more_traces = traces_d.gotoFirst(); more_traces; more_traces = traces_d.gotoNext()) { Trace* tmp = traces_d.getCurr(); if (trace_a == tmp) { return Error::handle(name(), L"addWithViterbi", Error::ARG, __FILE__, __LINE__); } // make sure the timestamps match even before we compare them // if (input_trace_frame_index == tmp->getFrame()) { if (trace_a->eq(*tmp)) { add_flag = true; // set the pointer of the trace that already exists // ptr_a = tmp; if (trace_a->getScore() > tmp->getScore()) { traces_d.remove(tmp); // delete the bad trace if possible // if (tmp->getRefCount() < 1) { tmp->setActive(false); } // add the new trace // traces_d.insertFirst(trace_a); return true; } else { trace_a->setActive(false); return false; } } } // there should not be a trace with an old time stamp - time synchronous // else { return Error::handle(name(), L"addWithViterbi", Error::ARG, __FILE__, __LINE__); } } // no trace is the same as the one to be added, add this one // if (!add_flag) { traces_d.insert(trace_a); } // exit gracefully // return true; } // method: addWithBaumWelch // // arguments: // Trace* trace: (input) the trace to add to the trace list. // Trace* ptr: (input) pointer to the existing trace with the same history // // return: a bool8 indicating status // // this method adds the trace to the trace list if it is the highest scoring // trace at that point // bool8 SearchNode::addWithBaumWelch(Trace* trace_a, Trace*& ptr_a) { // if there are no traces here, then just add this one // if (traces_d.isEmpty()) { traces_d.insertFirst(trace_a); return true; } // a flag showing that if need to add a trace // bool8 add_flag = false; ulong input_trace_frame_index = trace_a->getFrame(); // see if any other trace with the same history exists at this point // right now we loop over all traces at this point and compare histories // for (bool8 more_traces = traces_d.gotoFirst(); more_traces; more_traces = traces_d.gotoNext()) { Trace* tmp = traces_d.getCurr(); if (trace_a == tmp) { return Error::handle(name(), L"addWithBaumWelch", Error::ARG, __FILE__, __LINE__); } // make sure the timestamps match even before we compare them // if (input_trace_frame_index == tmp->getFrame()) { if (trace_a->eq(*tmp)) { add_flag = true; // set the pointer of the trace that already exists // ptr_a = tmp; // signal to delete the new incoming trace // return false; } } else { return Error::handle(name(), L"addWithBaumWelch", Error::ARG, __FILE__, __LINE__); } } // no trace is the same as the one to be added, add this one // if (!add_flag) { traces_d.insert(trace_a); } // exit gracefully // return true; } // method: clearTraceList // // arguments: none // // return: a bool8 indicating status // // this method clears the trace list (typically happens before every frame) // bool8 SearchNode::clearTraceList() { timestamp_d = -1; return traces_d.clear(); } // method: removeTrace // // arguments: // Trace* trace: (input) trace to remove from trace list of this node // // return: a bool8 indicating status // // this method removes trace from the trace list of the search node // bool8 SearchNode::removeTrace(Trace* trace_a) { // find the trace and remove it // if (traces_d.find(trace_a)) { traces_d.remove(); return true; } return false; } // method: addInstance // // arguments: // Instance* instance: (input) the instance to add to the instance list. // we do Viterbi pruning at this point // int32 timestamp: (input) the timestamp for the incoming instance // Instance* ptr: (input) pointer to existing instance with the same history // // return: a bool8 indicating status // // this method adds the instance to the instance list if it is the highest // scoring instance at that point // bool8 SearchNode::addInstance(Instance* instance_a, int32 timestamp_a, Instance*& ptr_a) { // declare local variables // bool8 status = true; if (this == &DiGraph::TERM_OBJ || this == &DiGraph::START_OBJ || isDummyNode()) { return status; } // output the debugging information // if (debug_level_d == Integral::ALL) { String output(L"attempting to adding instance: "); output.concat(instance_a); output.concat(L" to snode ["); SearchSymbol symbol; getSymbol(symbol); output.concat(symbol); output.concat(L"] old timestamp:"); output.concat(timestamp_d); output.concat(L" new timestamp:"); output.concat(timestamp_a); output.concat(L" num instances:"); output.concat(instances_d.length()); Console::put(output); } // check the timestamp // if (timestamp_a != timestamp_d) { instances_d.clear(); score_d = Instance::INACTIVE_SCORE; timestamp_d = timestamp_a; } // do Viterbi pruning - at this time, we only handle one-best Viterbi // if (instance_a->getInstanceMode() == Instance::TRAIN) { status = addWithBaumWelch(instance_a, ptr_a); } else { status = addWithViterbi(instance_a, ptr_a); } return status; } // method: addWithViterbi // // arguments: // Instance* instance: (input) the instance to add to the instance list. // we do Viterbi pruning at this point // Instance* ptr: (input) pointer to existing instance with the same history // // return: a bool8 indicating status // // this method adds the instance to the instance list if it is the highest // scoring instance at that point // bool8 SearchNode::addWithViterbi(Instance* instance_a, Instance*& ptr_a) { // if there are no instances here, then just add this one // if (instances_d.isEmpty()) { instances_d.insertFirst(instance_a); return true; } // a flag showing that if need to add a instance // bool8 add_flag = false; ulong input_instance_frame_index = instance_a->getFrame(); // see if any other instance with the same history exists at this point // right now we loop over all instances at this point and compare histories // for (bool8 more_instances = instances_d.gotoFirst(); more_instances; more_instances = instances_d.gotoNext()) { Instance* tmp = instances_d.getCurr(); if (instance_a == tmp) { return Error::handle(name(), L"addWithViterbi-- address same", SearchNode::ERR, __FILE__, __LINE__); } // make sure the timestamps match even before we compare them // if (input_instance_frame_index == tmp->getFrame()) { if (instance_a->eq(*tmp)) { add_flag = true; // set the pointer of the trace that already exists // ptr_a = tmp; if (instance_a->getScore() > tmp->getScore()) { instances_d.remove(tmp); // delete the bad instance if possible // if (tmp->getRefCount() < 1) { tmp->setActive(false); } // add the new instance // instances_d.insertFirst(instance_a); return true; } else { instance_a->setActive(false); return false; } } } else { return Error::handle(name(), L"addWithViterbi-- oldtime instance in node", Error::ARG, __FILE__, __LINE__, Error::WARNING); } } // no instance is the same as the one to be added, add this one // if (!add_flag) { instances_d.insert(instance_a); } // exit gracefully // return true; } // method: addWithBaumWelch // // arguments: // Instance* instance: (input) the instance to add to the instance list. // Instance* ptr: (input) pointer to existing instance with the same history // // return: a bool8 indicating status // // this method adds the instance to the instance list without prunning // bool8 SearchNode::addWithBaumWelch(Instance* instance_a, Instance*& ptr_a) { // if there are no instances here, then just add this one // if (instances_d.isEmpty()) { instances_d.insertFirst(instance_a); return true; } // a flag showing that if need to add a instance // bool8 add_flag = false; ulong input_instance_frame_index = instance_a->getFrame(); // see if any other instance with the same history exists at this point // right now we loop over all instances at this point and compare histories // for (bool8 more_instances = instances_d.gotoFirst(); more_instances; more_instances = instances_d.gotoNext()) { Instance* tmp = instances_d.getCurr(); if (instance_a == tmp) { return Error::handle(name(), L"addWithBaumWelch", Error::ARG, __FILE__, __LINE__); } // make sure the timestamps match even before we compare them // if (input_instance_frame_index == tmp->getFrame()) { if (instance_a->eq(*tmp)) { add_flag = true; // set the pointer of the instance that already exists // ptr_a = tmp; // signal to delete the new incoming instance // return false; } } else { return Error::handle(name(), L"addWithBaumWelch", Error::ARG, __FILE__, __LINE__); } } // no instance is the same as the one to be added, add this one // if (!add_flag) { instances_d.insert(instance_a); } // exit gracefully // return true; } // method: clearInstanceList // // arguments: none // // return: a bool8 indicating status // // this method clears the instance list (typically happens before every frame) // bool8 SearchNode::clearInstanceList() { timestamp_d = -1; return instances_d.clear(); } // method: removeInstance // // arguments: // Instance* instance: (input) instance to remove from instance list // // return: a bool8 indicating status // // this method removes instance from the instance list of the search node // bool8 SearchNode::removeInstance(Instance* instance_a) { // find the instance and remove it // for (bool8 more_instances = instances_d.gotoFirst(); more_instances; more_instances = instances_d.gotoNext()) { Instance* tmp = instances_d.getCurr(); if ( tmp == instance_a ){ instances_d.remove(); return true; } } return false; }