📄 lattice.cc
字号:
// remove all nodes
// (this also removes all transitions)
while (nodeIter.next(nodeIndex)) {
removeNode(nodeIndex);
}
maxIndex = 0;
}
// try to find a transition between the two given nodes.
// return 0, if there is no transition.
// return 1, if there is a transition.
LatticeTransition *
Lattice::findTrans(NodeIndex fromNodeIndex, NodeIndex toNodeIndex)
{
LatticeNode *toNode = nodes.find(toNodeIndex);
if (!toNode) {
// the end node does not exist.
return 0;
}
LatticeNode *fromNode = nodes.find(fromNodeIndex);
if (!fromNode) {
// the begin node does not exist.
return 0;
}
LatticeTransition *trans = toNode->inTransitions.find(fromNodeIndex);
if (!trans) {
// the transition does not exist.
return 0;
}
#ifdef DEBUG
LatticeTransition *outTrans = fromNode->outTransitions.find(toNodeIndex);
if (!outTrans) {
// asymmetric transition.
if (debug(DebugPrintFatalMessages)) {
dout() << "nonFatal error in Lattice::findTrans: asymmetric transition."
<< endl;
}
return 0;
}
#endif
return trans;
}
// to insert a transition between two nodes. If the transition exists already
// union their weights. maxAdd == 0, take the max of the existing and the new
// weights; maxAdd == 1, take the added weights of the two (notice that the
// weights are in log scale, so log(x+y) = logx + log (y/x + 1)
Boolean
Lattice::insertTrans(NodeIndex fromNodeIndex, NodeIndex toNodeIndex,
const LatticeTransition &t, Boolean maxAdd)
{
LatticeNode *toNode = nodes.find(toNodeIndex);
if (!toNode) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal error in Lattice::insertTrans: can't find toNode"
<< toNodeIndex << endl;
}
exit(-1);
}
LatticeNode *fromNode = nodes.find(fromNodeIndex);
if (!fromNode) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal error in Lattice::insertTrans: can't find fromNode"
<< fromNodeIndex << endl;
}
exit(-1);
}
Boolean found;
LatticeTransition *trans =
toNode->inTransitions.insert(fromNodeIndex, found);
if (!found) {
// it's a new edge;
*trans = t;
} else {
// there is already an edge
if (!maxAdd) {
trans->weight = unionWeights(trans->weight, t.weight);
} else {
trans->weight = (LogP)AddLogP(trans->weight, t.weight);
}
trans->flags = trans->flags | t.flags |
(!trans->getFlag(pauseTFlag) ? directTFlag : 0);
}
// duplicate intransition as outtransition
*fromNode->outTransitions.insert(toNodeIndex) = *trans;
return true;
}
Boolean
Lattice::setWeightTrans(NodeIndex fromNodeIndex, NodeIndex toNodeIndex,
LogP weight)
{
LatticeNode *toNode = nodes.find(toNodeIndex);
if (!toNode) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal error in Lattice::setWeightTrans: can't find toNode"
<< toNodeIndex << endl;
}
exit(-1);
}
LatticeTransition * trans = toNode->inTransitions.find(fromNodeIndex);
if (!trans) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal error in Lattice::setWeightTrans: can't find inTrans("
<< fromNodeIndex << "," << toNodeIndex << ")\n";
}
exit(-1);
}
trans->weight = weight;
LatticeNode *fromNode = nodes.find(fromNodeIndex);
if (!fromNode) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal error in Lattice::setWeightTrans: can't find fromNode"
<< fromNodeIndex << endl;
}
exit(-1);
}
trans = fromNode->outTransitions.find(toNodeIndex);
if (!trans) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal error in Lattice::setWeightTrans: can't find outTrans ("
<< fromNodeIndex << "," << toNodeIndex << ")\n";
}
exit(-1);
}
trans->weight = weight;
return true;
}
Boolean
Lattice::removeTrans(NodeIndex fromNodeIndex, NodeIndex toNodeIndex)
{
LatticeNode *fromNode = nodes.find(fromNodeIndex);
if (!fromNode) {
if (debug(DebugPrintOutLoop)) {
dout() << "nonFatal error in Lattice::removeTrans:\n"
<< " undefined source node in transition "
<< "(" << fromNodeIndex << ", " << toNodeIndex << ")\n";
}
return false;
}
LatticeTransition * outTrans =
fromNode->outTransitions.remove(toNodeIndex);
if (!outTrans) {
if (debug(DebugPrintOutLoop)) {
dout() << "nonFatal error in Lattice::removeTrans:\n"
<< " no outTrans (" << fromNodeIndex << ", "
<< toNodeIndex << ")\n";
}
return false;
}
LatticeNode *toNode = nodes.find(toNodeIndex);
if (!toNode) {
if (debug(DebugPrintOutLoop)) {
dout() << "nonFatal error in Lattice::removeTrans:\n"
<< "undefined sink node " << toNodeIndex << endl;
}
return false;
}
LatticeTransition * inTrans =
toNode->inTransitions.remove(fromNodeIndex);
if (!inTrans) {
if (debug(DebugPrintOutLoop)) {
dout() << "nonFatal error in Lattice::removeTrans:\n"
<< " no inTrans (" << fromNodeIndex << ", "
<< toNodeIndex << ")\n";
}
return false;
}
return true;
}
void
Lattice::markTrans(NodeIndex fromNodeIndex, NodeIndex toNodeIndex, unsigned flag)
{
LatticeNode *fromNode = nodes.find(fromNodeIndex);
if (!fromNode) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal Error in Lattice::markTrans: can't find source node"
<< fromNodeIndex << endl;
}
exit(-1);
}
LatticeTransition * trans = fromNode->outTransitions.find(toNodeIndex);
if (!trans) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal Error in Lattice::markTrans: can't find outTrans ("
<< fromNodeIndex << ", " << toNodeIndex << ")\n";
}
exit(-1);
}
trans->flags |= flag;
LatticeNode *toNode = nodes.find(toNodeIndex);
if (!toNode) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal Error in Lattice::markTrans: can't find sink node"
<< toNodeIndex << endl;
}
exit(-1);
}
trans = toNode->inTransitions.find(fromNodeIndex);
if (!trans) {
if (debug(DebugPrintFatalMessages)) {
dout() << "Fatal Error in Lattice::markTrans: can't find inTrans ("
<< toNodeIndex << ", " << toNodeIndex << ")\n";
}
exit(-1);
}
trans->flags |= flag;
}
void
Lattice::clearMarkOnAllNodes(unsigned flag) {
LHashIter<NodeIndex, LatticeNode> nodeIter(nodes);
NodeIndex nodeIndex;
while (LatticeNode *node = nodeIter.next(nodeIndex)) {
node->flags &= ~flag;
}
}
void
Lattice::dumpFlags() {
LHashIter<NodeIndex, LatticeNode> nodeIter(nodes, nodeSort);
NodeIndex nodeIndex;
while (LatticeNode *node = nodeIter.next(nodeIndex)) {
dout() << "node " << nodeIndex << " flags = " << node->flags << endl;
TRANSITER_T<NodeIndex,LatticeTransition> outIter(node->outTransitions);
NodeIndex outIndex;
while (LatticeTransition *outTrans = outIter.next(outIndex)) {
dout() << " trans -> " << outIndex
<< " flags = " << outTrans->flags << endl;
}
TRANSITER_T<NodeIndex,LatticeTransition> inIter(node->inTransitions);
NodeIndex inIndex;
while (LatticeTransition *inTrans = inIter.next(inIndex)) {
dout() << " trans <- " << inIndex
<< " flags = " << inTrans->flags << endl;
}
}
}
void
Lattice::clearMarkOnAllTrans(unsigned flag) {
LHashIter<NodeIndex, LatticeNode> nodeIter(nodes);
NodeIndex nodeIndex;
while (LatticeNode *node = nodeIter.next(nodeIndex)) {
TRANSITER_T<NodeIndex,LatticeTransition> outIter(node->outTransitions);
NodeIndex outIndex;
while (LatticeTransition *outTrans = outIter.next(outIndex)) {
outTrans->flags &= ~flag;
}
TRANSITER_T<NodeIndex,LatticeTransition> inIter(node->inTransitions);
NodeIndex inIndex;
while (LatticeTransition *inTrans = inIter.next(inIndex)) {
inTrans->flags &= ~flag;
}
}
}
// compute 'or' operation on two input lattices
// using implantLattice,
// assume that the initial state of this lattice is empty.
Boolean
Lattice::latticeOr(Lattice &lat1, Lattice &lat2)
{
initial = 1;
final = 0;
if (debug(DebugPrintFunctionality)) {
dout() << "Lattice::latticeOr: doing OR on "
<< lat1.getName() << " and " << lat2.getName() << "\n";
}
// if name is default, inherit if from the input lattice
if (strcmp(name, LATTICE_NONAME) == 0) {
free((void *)name);
name = strdup(lat1.name);
assert(name != 0);
}
// inherit HTK header info from first lattice
htkheader = lat1.htkheader;
LatticeNode *newNode = nodes.insert(0);
newNode->word = Vocab_None;
newNode->flags = 0;
// get initial time as the minimum of the start times of the two lattices
LatticeNode *initialNode1 = lat1.findNode(lat1.initial);
LatticeNode *initialNode2 = lat2.findNode(lat2.initial);
if (initialNode1->htkinfo != 0 &&
initialNode1->htkinfo->time != HTK_undef_float ||
initialNode2->htkinfo != 0 &&
initialNode2->htkinfo->time != HTK_undef_float)
{
HTKWordInfo *linkinfo = new HTKWordInfo;
assert(linkinfo != 0);
newNode->htkinfo = htkinfos[htkinfos.size()] = linkinfo;
if (initialNode1->htkinfo == 0 ||
initialNode1->htkinfo->time == HTK_undef_float ||
(initialNode2->htkinfo != 0 &&
initialNode2->htkinfo->time != HTK_undef_float &&
initialNode1->htkinfo->time > initialNode2->htkinfo->time))
{
linkinfo->time = initialNode2->htkinfo->time;
} else {
linkinfo->time = initialNode1->htkinfo->time;
}
}
newNode = nodes.insert(1);
newNode->word = Vocab_None;
newNode->flags = 0;
// get final time as the maximum of the end times of the two lattices
LatticeNode *finalNode1 = lat1.findNode(lat1.final);
LatticeNode *finalNode2 = lat2.findNode(lat2.final);
if (finalNode1->htkinfo != 0 &&
finalNode1->htkinfo->time != HTK_undef_float ||
finalNode2->htkinfo != 0 &&
finalNode2->htkinfo->time != HTK_undef_float)
{
HTKWordInfo *linkinfo = new HTKWordInfo;
assert(linkinfo != 0);
newNode->htkinfo = htkinfos[htkinfos.size()] = linkinfo;
if (finalNode1->htkinfo == 0 ||
finalNode1->htkinfo->time == HTK_undef_float ||
(finalNode2->htkinfo != 0 &&
finalNode2->htkinfo->time != HTK_undef_float &&
finalNode1->htkinfo->time < finalNode2->htkinfo->time))
{
linkinfo->time = finalNode2->htkinfo->time;
} else {
linkinfo->time = finalNode1->htkinfo->time;
}
}
newNode = nodes.insert(2);
newNode->word = Vocab_None;
newNode->flags = 0;
newNode = nodes.insert(3);
newNode->word = Vocab_None;
newNode->flags = 0;
maxIndex = 4;
LatticeTransition t(0, 0);
insertTrans(1, 2, t);
insertTrans(1, 3, t);
insertTrans(2, 0, t);
insertTrans(3, 0, t);
if (!(implantLattice(2, lat1))) return false;
if (!(implantLattice(3, lat2))) return false;
limitIntlogs = lat1.limitIntlogs || lat2.limitIntlogs;
return true;
}
Boolean
Lattice::latticeCat(Lattice &lat1, Lattice &lat2, float interSegmentTime)
{
initial = 1;
final = 0;
if (debug(DebugPrintFunctionality)) {
dout() << "Lattice::latticeCat: doing CONCATENATE on "
<< lat1.getName() << " and " << lat2.getName() << "\n";
}
// if name is default, inherit if from the input lattice
if (strcmp(name, LATTICE_NONAME) == 0) {
free((void *)name);
name = strdup(lat1.name);
assert(name != 0);
}
// inherit HTK header info from first lattice
htkheader = lat1.htkheader;
LatticeNode *newNode = nodes.insert(1);
newNode->word = Vocab_None;
newNode->flags = 0;
// get initial time from first lattice
LatticeNode *initialNode1 = lat1.findNode(lat1.initial);
if (initialNode1->htkinfo != 0 &&
initialNode1->htkinfo->time != HTK_undef_float)
{
HTKWordInfo *linkinfo = new HTKWordInfo;
assert(linkinfo != 0);
newNode->htkinfo = htkinfos[htkinfos.size()] = linkinfo;
linkinfo->time = initialNode1->htkinfo->time;
}
// get final time from first lattice
float finalTime1 = 0.0;
LatticeNode *finalNode1 = lat1.findNode(lat1.final);
if (finalNode1->htkinfo != 0 &&
finalNode1->htkinfo->time != HTK_undef_float)
{
finalTime1 = finalNode1->htkinfo->time;
}
newNode = nodes.insert(0);
newNode->word = Vocab_None;
newNode->flags = 0;
// get final time from second lattice
LatticeNode *finalNode2 = lat2.findNode(lat2.final);
if (finalNode2->htkinfo != 0 &&
finalNode2->htkinfo->time != HTK_undef_float)
{
HTKWordInfo *linkinfo = new HTKWordInfo;
assert(linkinfo != 0);
newNode->htkinfo = htkinfos[htkinfos.size()] = linkinfo;
// add interSegmentTime and final time, which are zero if no times were found
linkinfo->time = finalNode2->htkinfo->time + interSegmentTime + finalTime1;
}
if (interSegmentTime != 0.0) {
newNode = nodes.insert(2);
newNode->word = Vocab_None;
newNode->flags = 0;
newNode = nodes.insert(3);
newNode->word = vocab.pauseIndex();
HTKWordInfo *linkinfo = new HTKWordInfo;
assert(linkinfo != 0);
newNode->htkinfo = htkinfos[htkinfos.size()] = linkinfo;
linkinfo->time = finalTime1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -