///////////////////////////////////////////////////////////////////////////////
// //
// This file is part of ModelBlocks. Copyright 2009, ModelBlocks developers. //
// //
// ModelBlocks is free software: you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation, either version 3 of the License, or //
// (at your option) any later version. //
// //
// ModelBlocks is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with ModelBlocks. If not, see . //
// //
// ModelBlocks developers designate this particular file as subject to //
// the "Moses" exception as provided by ModelBlocks developers in //
// the LICENSE file that accompanies this code. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _NL_HMM_
#define _NL_HMM_
#include
#include
#include
#include
//#include
//#include
//#include
#include "nl-prob.h"
#include "nl-safeids.h"
#include "nl-beam.h"
typedef int Frame;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// NullBackDat - default empty back-pointer data; can replace with word or sem relation
//
////////////////////////////////////////////////////////////////////////////////
template
class NullBackDat {
static const string sDummy;
public:
NullBackDat () {}
NullBackDat (const MY& my) {}
void write (FILE*) const {}
string getString() const { return sDummy; }
};
template
const string NullBackDat::sDummy ( "" );
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Index - pointer to source in previous beam heap
//
////////////////////////////////////////////////////////////////////////////////
class Index : public Id {
public:
Index ( ) { }
Index (int i) {set(i);}
Index& operator++ ( ) {set(toInt()+1); return *this;}
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// TrellNode - node in viterbi trellis
//
////////////////////////////////////////////////////////////////////////////////
template
class TrellNode {
private:
// Data members...
Index indSource;
B backptrData;
S sId;
LogProb lgprMax;
public:
// Constructor / destructor methods...
TrellNode ( ) { }
TrellNode ( const Index& indS, const S& sI, const B& bDat, LogProb lgpr)
{ indSource=indS; sId=sI; lgprMax=lgpr; backptrData=bDat; /* fo = -1; */ }
// Specification methods...
const Index& setSource ( ) const { return indSource; }
const B& setBackData( ) const { return backptrData; }
const S& setId ( ) const { return sId; }
LogProb& setScore ( ) { return lgprMax; }
// Extraction methods...
bool operator== ( const TrellNode& tnsb ) const { return(sId==tnsb.sId); }
// size_t getHashKey ( ) const { return sId.getHashKey(); }
const Index& getSource ( ) const { return indSource; }
const B& getBackData( ) const { return backptrData; }
const S& getId ( ) const { return sId; }
LogProb getLogProb ( ) const { return lgprMax; }
LogProb getScore ( ) const { return lgprMax; }
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// HMM
//
////////////////////////////////////////////////////////////////////////////////
template >
class HMM {
private:
typedef std::pair IB;
// Data members...
const MY& my;
const MX& mx;
SafeArray2D,Id,TrellNode > aatnTrellis;
Frame frameLast;
int iNextNode;
public:
// Static member varaibles...
static bool OUTPUT_QUIET;
static bool OUTPUT_NOISY;
static bool OUTPUT_VERYNOISY;
static int BEAM_WIDTH;
// Constructor / destructor methods...
HMM ( const MY& my1, const MX& mx1 ) : my(my1), mx(mx1) { }
// Specification methods...
void init ( int, int, const S& ) ;
void init ( int, int, SafeArray1D,pair >* );
void updateRanked ( const typename MX::RandVarType&, bool ) ;
void updateSerial ( const typename MX::RandVarType& ) ;
void updatePara ( const typename MX::RandVarType& ) ;
bool unknown ( const typename MX::RandVarType& ) ;
void each ( const typename MX::RandVarType&, Beam&, SafeArray1D,std::pair,LogProb> >& ) ;
// Extraction methods...
const TrellNode& getTrellNode ( int i ) const { return aatnTrellis.get(frameLast,i); }
int getBeamUsed ( int ) const ;
// Input / output methods...
void writeMLS ( FILE* ) const ;
void writeMLS ( FILE*, const S& ) const ;
void debugPrint() const;
double getCurrSum(int) const;
//void writeCurr ( FILE*, int ) const ;
void writeCurr ( ostream&, int ) const ;
void writeCurrSum ( FILE*, int ) const ;
void gatherElementsInBeam( SafeArray1D,pair >* result, int f ) const;
void writeCurrEntropy ( FILE*, int ) const;
//void writeCurrDepths ( FILE*, int ) const;
void writeFoll ( FILE*, int, int, const typename MX::RandVarType& ) const ;
void writeFollRanked ( FILE*, int, int, const typename MX::RandVarType&, bool ) const ;
std::list getMLS() const;
std::list > getMLSnodes() const;
std::list getMLS(const S&) const;
std::list > getMLSnodes(const S&) const;
};
template bool HMM::OUTPUT_QUIET = false;
template bool HMM::OUTPUT_NOISY = false;
template bool HMM::OUTPUT_VERYNOISY = false;
template int HMM::BEAM_WIDTH = 1;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
template
void HMM::init ( int numFr, int numS, const S& s ) {
// Alloc trellis...
BEAM_WIDTH = numS;
aatnTrellis.init(numFr,BEAM_WIDTH);
frameLast=0;
// Set initial element at first time slice...
aatnTrellis.set(frameLast,0) = TrellNode ( Index(0), s, B(), 0 ) ;
}
template
void HMM::init ( int numFr, int beamSize, SafeArray1D,pair >* existingBeam ) {
// Alloc trellis...
// int numToCopy = existingBeam->getSize();
BEAM_WIDTH = beamSize;
aatnTrellis.init(numFr,BEAM_WIDTH);
frameLast=0;
// Set initial beam elements at first time slice...
for ( int i=0, n=existingBeam->getSize(); i ( Index(0), existingBeam->get(i).first, B(), existingBeam->get(i).second ) ;
}
}
template
void HMM::debugPrint() const{
for (int frame=0, numFrames=aatnTrellis.getxSize(); frame 0) {
cerr << "\t" << "aatnTrellis.get(frame=" << frame << ",beamIndex=" << beamIndex << ") is\t" << aatnTrellis.get(frame,beamIndex).getId() << "\tprob=" << aatnTrellis.get(frame,beamIndex).getLogProb().toDouble() << endl;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
template
bool outRank ( const quad >& a1,
const quad >& a2 ) { return (a1.third>a2.third); }
template
bool HMM::unknown( const typename MX::RandVarType& x ) {
return mx.unknown(x);
}
template
void HMM::updateRanked ( const typename MX::RandVarType& x, bool b1 ) {
// Increment frame counter...
frameLast++;
// Init beam for new frame...
Beam btn(BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted (BEAM_WIDTH);
Heap < quad >, outRank > ashpiQueue;
typedef quad > SHPI;
SHPI shpi, shpiTop;
int aCtr;
ashpiQueue.clear();
//shpi.first = -1;
//shpi.second = HModel::IterVal();
//shpi.third = 1.0;
shpi.first = 0;
shpi.third = aatnTrellis.get(frameLast-1,shpi.first).getScore();
shpi.third *= my.setIterProb ( shpi.second, aatnTrellis.get(frameLast-1,shpi.first).getId(), x, b1, aCtr=-1 );
//S s; my.setTrellDat(s,shpi.second);
shpi.fourth = -1;
////cerr<<"????? "<0; iTrg++ ) {
// Iterate A* (best-first) search until a complete path is at the top of the queue...
while ( ashpiQueue.getSize() > 0 && ashpiQueue.getTop().fourth < MY::IterVal::NUM_ITERS ) {
// Remove top...
shpiTop = ashpiQueue.dequeueTop();
// Fork off (try to advance each elementary variable a)...
for ( int a=shpiTop.fourth.toInt(); a<=MY::IterVal::NUM_ITERS; a++ ) {
// Copy top into new queue element...
shpi = shpiTop;
// At variable position -1, advance beam element for transition source...
if ( a == -1 ) shpi.first++;
// Incorporate prob from transition source...
shpi.third = aatnTrellis.get(frameLast-1,shpi.first).getScore();
if ( shpi.third > LogProb() ) {
// Try to advance variable at position a and return probability (subsequent variables set to first, probability ignored)...
shpi.third *= my.setIterProb ( shpi.second, aatnTrellis.get(frameLast-1,shpi.first).getId(), x, b1, aCtr=a );
// At end of variables, incorporate observation probability...
if ( a == MY::IterVal::NUM_ITERS && shpi.fourth != MY::IterVal::NUM_ITERS )
{ S s; my.setTrellDat(s,shpi.second); shpi.third *= mx.getProb(x,s); }
// Record variable position at which this element was forked off...
shpi.fourth = a;
//cerr<<" from partial: "< LogProb() ) {
////if ( frameLast == 4 ) cerr<<" from partial: "< 0 ) {
S s; my.setTrellDat(s,ashpiQueue.getTop().second);
bFull |= btn.tryAdd ( s, IB(ashpiQueue.getTop().first,my.setBackDat(ashpiQueue.getTop().second)), ashpiQueue.getTop().third );
////cerr<,LogProb>* tn1 = &atnSorted.get(i);
aatnTrellis.set(frameLast,i)=TrellNode(tn1->first.second.first,
tn1->first.first,
tn1->first.second.second,
tn1->second);
}
my.update();
}
////////////////////////////////////////////////////////////////////////////////
template
void HMM::updateSerial ( const typename MX::RandVarType& x ) {
// Increment frame counter...
frameLast++;
// Init beam for new frame...
Beam btn(BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted (BEAM_WIDTH);
// // Copy beam to trellis...
// for ( int i=0; i& tnsbPrev = aatnTrellis.get(frameLast-1,i);
S sPrev = tnsbPrev.getId();
// If prob still not below beam minimum...
if ( aatnTrellis.get(frameLast-1,i).getLogProb() > btn.getMin().getScore() ) {
//if (OUTPUT_VERYNOISY) { fprintf(stderr,"FROM: "); sPrev.write(stderr); fprintf(stderr,"\n"); }
// For each possible transition...
typename MY::IterVal y;
for ( bool b=my.setFirst(y,sPrev); b; b=my.setNext(y,sPrev) ) {
//if (OUTPUT_VERYNOISY) { fprintf(stderr," TO: "); y.write(stderr); fprintf(stderr," %d*%d*%d\n",tnsbPrev.getLogProb().toInt(),lgprY.toInt(),lgprO.toInt()); }
S s;
#ifdef X_BEFORE_Y
LogProb lgprX = mx.getProb(x,my.setTrellDat(s,y)); if ( !OUTPUT_VERYNOISY && LogProb()==lgprX ) continue;
LogProb lgprY = my.getProb(y,sPrev); if ( !OUTPUT_VERYNOISY && LogProb()==lgprY ) continue;
#else
LogProb lgprY = my.getProb(y,sPrev); if ( !OUTPUT_VERYNOISY && LogProb()==lgprY ) continue;
LogProb lgprX = mx.getProb(x,my.setTrellDat(s,y)); if ( !OUTPUT_VERYNOISY && LogProb()==lgprX ) continue;
#endif
LogProb lgprFull = aatnTrellis.get(frameLast-1,i).getLogProb() * lgprY * lgprX;
if (OUTPUT_VERYNOISY) {
cout<<" "< "< ",tnsbPrev.getLogProb().toInt(),lgprY.toInt(),lgprX.toInt(),lgprFull.toInt());
//y.write(stdout); fprintf(stdout," "); s.write(stdout);
//fprintf(stdout,"\n");
}
// Incorporate into trellis...
btn.tryAdd ( s, IB(i,my.setBackDat(y)), lgprFull );
//if(OUTPUT_VERYNOISY)
// fprintf ( stderr," (S_t-1:[e^%0.6f] * Y:e^%0.6f * X:e^%0.6f = S_t:[e^%0.6f])\n",
// float(aatnTrellis.get(frameLast-1,i).getLogProb().toInt())/100.0,
// float(lgprY.toInt())/100.0,
// float(lgprX.toInt())/100.0,
// float(lgprFull.toInt())/100.0 ) ;
}
}
}
// for(int i=0;i "); btn.get(i)->first.write(stderr); fprintf(stderr,"\n");
// }
btn.sort(atnSorted);
// Copy sorted beam to trellis...
for(int i=0;i,LogProb>* tn1 = &atnSorted.get(i);
aatnTrellis.set(frameLast,i)=TrellNode(tn1->first.second.first,
tn1->first.first,
tn1->first.second.second,
tn1->second);
}
}
////////////////////////////////////////////////////////////////////////////////
/*
boost::mutex mutexHmmCtrSema;
boost::mutex mutexHmmParanoiaLock;
template
void HMM::each ( const typename MX::RandVarType& x, Beam& btn, SafeArray1D,std::pair,LogProb> >& atnOut ) {
//// for(int j=0; j<100; j+=1) for(int i=0; i<1000000; i+=1); // peg processor
//{
// boost::mutes::scoped_lock lock1(mutexHmmParanoiaLock);
while ( true ) {
int i;
bool bStop=false;
{ boost::mutex::scoped_lock lock(mutexHmmCtrSema);
if ( (i=iNextNode) < BEAM_WIDTH ) iNextNode++;
else bStop = true;
} // locked to ensure no double-duty
if ( bStop ) break;
const TrellNode& tnsbPrev = aatnTrellis.get(frameLast-1,i);
// If prob still not below beam minimum...
if ( tnsbPrev.getLogProb() > btn.getMin().getScore() ) {
//if (OUTPUT_VERYNOISY) { fprintf(stderr,"FROM: "); tnsbPrev.getId().write(stderr); fprintf(stderr,"\n"); }
// For each possible transition...
const S& sPrev = tnsbPrev.getId();
typename MY::IterVal y;
for ( bool b=my.setFirst(y,sPrev); b; b=my.setNext(y,sPrev) ) {
S s;
LogProb lgprX;
LogProb lgprY;
LogProb lgprFull;
#ifdef X_BEFORE_Y //////////////////////////////////////////////////////
lgprX = mx.getProb(x,my.setTrellDat(s,y)); if ( !OUTPUT_VERYNOISY && LogProb()==lgprX ) continue;
lgprY = my.getProb(y,sPrev); if ( !OUTPUT_VERYNOISY && LogProb()==lgprY ) continue;
#else //////////////////////////////////////////////////////////////////
lgprY = my.getProb(y,sPrev); if ( !OUTPUT_VERYNOISY && LogProb()==lgprY ) continue;
lgprX = mx.getProb(x,my.setTrellDat(s,y)); if ( !OUTPUT_VERYNOISY && LogProb()==lgprX ) continue;
#endif /////////////////////////////////////////////////////////////////
lgprFull = tnsbPrev.getLogProb() * lgprY * lgprX;
if (OUTPUT_VERYNOISY) {
boost::mutex::scoped_lock lock1(mutexHmmParanoiaLock);
//fprintf(stderr," TO: "); y.write(stderr); fprintf(stderr,"\n");
cout<<" "< "< ",tnsbPrev.getLogProb().toInt(),lgprY.toInt(),lgprO.toInt(),lgprFull.toInt());
//y.write(stdout); fprintf(stdout," "); s.write(stdout);
//fprintf(stdout,"\n");
}
// Incorporate into trellis...
btn.tryAdd ( s, IB(i,my.setBackDat(y)), lgprFull );
// if(OUTPUT_VERYNOISY)
// fprintf ( stderr," (S_t-1:[e^%0.6f] * Y:e^%0.6f * X:e^%0.6f = S_t:[e^%0.6f])\n",
// float(aatnTrellis.get(frameLast-1,i).getLogProb().toInt())/100.0,
// float(lgprY.toInt())/100.0,
// float(lgprO.toInt())/100.0,
// float(lgprFull.toInt())/100.0 ) ;
}
}
}
if (OUTPUT_NOISY)
{ boost::mutex::scoped_lock lock1(mutexHmmParanoiaLock);
//// btn.sort(atnOut);
fprintf(stdout,"========================================\n");
for(int i=0;ifirst<<":"<second.second.first.toInt()<<":"<first.write(stdout); fprintf(stdout,":%d:%d\n",btn.get(i)->second.second.first.toInt(),btn.get(i).getScore().toInt());
//// atnOut.get(i).first.first.write(stdout); fprintf(stdout,":%d\n",(int)atnOut.get(i).second);
}
fprintf(stdout,"----------------------------------------\n");
}
//}
}
//// Something there is (about boost::bind) that doesn't love a ref. So use a pointer for hmm and beam.
template
void global_parahmm_each ( HMM* phmm, const typename MX::RandVarType* px, Beam >* pbtn,
SafeArray1D,std::pair >,LogProb> >* patn ) {
//void HMM::each_static ( HMM* phmm, const MX& x, Beam* pbtn, SafeArray1D,LogProb> >* patn ) {
phmm->each(*px,*pbtn,*patn);
}
template
void HMM::updatePara ( const typename MX::RandVarType& o ) {
// Increment frame counter...
frameLast++;
// fprintf(stdout,"++++%d",frameLast); o.write(stdout); fprintf(stdout,"\n");
// Init beam for new frame...
Beam btn1 (BEAM_WIDTH);
Beam btn2 (BEAM_WIDTH);
Beam btn3 (BEAM_WIDTH);
Beam btn4 (BEAM_WIDTH);
Beam btn5 (BEAM_WIDTH);
Beam btn6 (BEAM_WIDTH);
Beam btn7 (BEAM_WIDTH);
Beam btn8 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted1 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted2 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted3 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted4 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted5 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted6 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted7 (BEAM_WIDTH);
SafeArray1D,std::pair,LogProb> > atnSorted8 (BEAM_WIDTH);
//if(0==frameLast%20)
// fprintf(stderr,"frame %d...\n",frameLast);
iNextNode=0;
boost::thread th1(boost::bind(&global_parahmm_each,this,&o,&btn1,&atnSorted1));
boost::thread th2(boost::bind(&global_parahmm_each,this,&o,&btn2,&atnSorted2));
boost::thread th3(boost::bind(&global_parahmm_each,this,&o,&btn3,&atnSorted3));
boost::thread th4(boost::bind(&global_parahmm_each,this,&o,&btn4,&atnSorted4));
boost::thread th5(boost::bind(&global_parahmm_each,this,&o,&btn5,&atnSorted5));
boost::thread th6(boost::bind(&global_parahmm_each,this,&o,&btn6,&atnSorted6));
boost::thread th7(boost::bind(&global_parahmm_each,this,&o,&btn7,&atnSorted7));
boost::thread th8(boost::bind(&global_parahmm_each,this,&o,&btn8,&atnSorted8));
th1.join();
th2.join();
th3.join();
th4.join();
th5.join();
th6.join();
th7.join();
th8.join();
for(int i=0;ifirst, btn2.get(i)->second.second, btn2.get(i).getScore());
btn1.tryAdd(btn3.get(i)->first, btn3.get(i)->second.second, btn3.get(i).getScore());
btn1.tryAdd(btn4.get(i)->first, btn4.get(i)->second.second, btn4.get(i).getScore());
btn1.tryAdd(btn5.get(i)->first, btn5.get(i)->second.second, btn5.get(i).getScore());
btn1.tryAdd(btn6.get(i)->first, btn6.get(i)->second.second, btn6.get(i).getScore());
btn1.tryAdd(btn7.get(i)->first, btn7.get(i)->second.second, btn7.get(i).getScore());
btn1.tryAdd(btn8.get(i)->first, btn8.get(i)->second.second, btn8.get(i).getScore());
}
btn1.sort(atnSorted1);
for(int i=0;i,LogProb>* tn1 = &atnSorted1.get(i);
aatnTrellis.set(frameLast,i)=TrellNode(tn1->first.second.first,
tn1->first.first,
tn1->first.second.second,
tn1->second);
}
// for(int i=0;i(btn1.get(i)->second.second.first,
// btn1.get(i)->first,
// btn1.get(i)->second.second.second,
// btn1.get(i).getScore());
// }
}
*/
////////////////////////////////////////////////////////////////////////////////
template
void HMM::writeMLS ( FILE* pf ) const {
// Find best value at last frame...
int iBest = 0;
LogProb lgprEnd ;
for ( int i=0; i aatnTrellis.get(frameLast,iBest).getLogProb()) ? i : iBest ;
lgprEnd = aatnTrellis.get(frameLast,iBest).getLogProb();
if(lgprEnd == LogProb()){
fprintf(pf, "WARNING: There is no most likely sequence\n");
return;
}
// Trace back most likely sequence...
for ( Frame fr=frameLast; fr-1>=0; iBest=aatnTrellis.get(fr--,iBest).getSource().toInt() ) {
fprintf(pf,"HYPOTH %04d> ",fr-1);
String str; str<
void HMM::writeMLS ( FILE* pf, const S& sLast ) const {
// Find best value at last frame...
int iBest = -1;
LogProb lgprEnd ;
for ( int i=0; i aatnTrellis.get(frameLast,iBest).getLogProb()) ? i : iBest ;
// iBest = i;
if ( -1==iBest ) iBest=0;
lgprEnd = aatnTrellis.get(frameLast,iBest).getLogProb();
if(lgprEnd == LogProb()){
fprintf(pf, "WARNING: There is no most likely sequence\n");
return;
}
// Trace back most likely sequence...
for ( Frame fr=frameLast; fr-1>=0; iBest=aatnTrellis.get(fr--,iBest).getSource().toInt() ) {
fprintf(pf,"HYPOTH %04d> ",fr-1);
String str; str<
std::list HMM::getMLS() const {
std::list rList;
int iBest = 0;
LogProb lgprEnd;
for ( int i=0; i aatnTrellis.get(frameLast,iBest).getLogProb()) ? i : iBest ;
lgprEnd = aatnTrellis.get(frameLast,iBest).getLogProb();
if(lgprEnd == LogProb()){
string r = "WARNING: There is no most likely sequence\n";
rList.push_front(r);
return rList;
}
// Trace back most likely sequence...
for ( Frame fr=frameLast; fr-1>=0; iBest=aatnTrellis.get(fr--,iBest).getSource().toInt() ) {
char tmp[14];
sprintf(tmp,"HYPOTH %04d> ", fr-1);
string tString(tmp);
tString += aatnTrellis.get(fr,iBest).getId().getString() + " " +
aatnTrellis.get(fr,iBest).getBackData().getString() + "\n";
rList.push_front(tString);
}
return rList;
}
/* for getting MLS in struct form... */
template
std::list > HMM::getMLSnodes() const {
std::list > rList;
int iBest = 0;
LogProb lgprEnd;
for ( int i=0; i aatnTrellis.get(frameLast,iBest).getLogProb()) ? i : iBest ;
lgprEnd = aatnTrellis.get(frameLast,iBest).getLogProb();
if(lgprEnd == LogProb()){
fprintf(stderr, "WARNING: There is no most likely sequence\n");
return rList;
}
// Trace back most likely sequence...
for ( Frame fr=frameLast; fr-1>=0; iBest=aatnTrellis.get(fr--,iBest).getSource().toInt() )
rList.push_front(aatnTrellis.get(fr,iBest));
return rList;
}
/* for getting the MLS in string form... */
template
std::list HMM::getMLS(const S& sLast) const {
std::list rList;
int iBest = -1;
LogProb lgprEnd;
for ( int i=0; i aatnTrellis.get(frameLast,iBest).getLogProb()) ? i : iBest ;
// iBest = i;
if ( -1==iBest ) iBest=0;
lgprEnd = aatnTrellis.get(frameLast,iBest).getLogProb();
if(lgprEnd == LogProb()){
string r = "WARNING: There is no most likely sequence\n";
rList.push_front(r);
return rList;
}
// Trace back most likely sequence...
for ( Frame fr=frameLast; fr-1>=0; iBest=aatnTrellis.get(fr--,iBest).getSource().toInt() ) {
//// char tmp[14];
//// sprintf(tmp,"HYPOTH %04d> ", fr-1);
//// string tString(tmp);
//// tString +=
string tString =
//// aatnTrellis.get(fr,iBest).getId().getString() + " " +
aatnTrellis.get(fr,iBest).getBackData().getString()
//// + "\n"
;
tString = (B().getString()==tString) ? "" : " " + tString; // zero out or add space
rList.push_front(tString);
}
return rList;
}
/* for getting MLS in struct form... */
template
std::list > HMM::getMLSnodes(const S& sLast) const {
std::list > rList;
int iBest = -1;
LogProb lgprEnd;
for ( int i=0; i aatnTrellis.get(frameLast,iBest).getLogProb()) ? i : iBest ;
// iBest = i;
if ( -1==iBest ) iBest=0;
lgprEnd = aatnTrellis.get(frameLast,iBest).getLogProb();
if(lgprEnd == LogProb()){
fprintf(stderr, "WARNING: There is no most likely sequence\n");
return rList;
}
// Trace back most likely sequence...
for ( Frame fr=frameLast; fr-1>=0; iBest=aatnTrellis.get(fr--,iBest).getSource().toInt() )
rList.push_front(aatnTrellis.get(fr,iBest));
return rList;
}
////////////////////////////////////////////////////////////////////////////////
template
//void HMM::writeCurr ( FILE* pf, int f=-1 ) const {
void HMM::writeCurr ( ostream& os, int f=-1 ) const {
if ( -1==f ) f=frameLast;
if ( 0<=f && f<=frameLast )
for ( int i=0; i0){
//fprintf(pf," (from ");
//String str; str<
void HMM::writeCurrSum ( FILE* pf, int f=-1 ) const {
if ( -1==f ) f=frameLast;
if ( 0<=f && f<=frameLast ) {
LogProb sum = 0.0;
LogProb logtop = 0.0;
for ( int i=0; i
double HMM::getCurrSum ( int f=-1 ) const {
if ( -1==f ) f=frameLast;
if ( 0<=f && f<=frameLast ) {
LogProb negInfinity;
double sum = 0;
//LogProb logtop = 0;
int sumCount=0;
for ( int i=0; i
void HMM::gatherElementsInBeam( SafeArray1D,pair >* result, int f=-1) const {
result->init(BEAM_WIDTH);
if ( -1==f ) f=frameLast;
if ( 0<=f && f<=frameLast ) {
for ( int i=0; iset(i).first = aatnTrellis.get(f,i).getId();
result->set(i).second = aatnTrellis.get(f,i).getLogProb();
}
} else {
//TODO How should exceptional situations be handled?
cerr << "ERROR: Invalid argument " << f << " to gatherElementsInBeam" << endl;
}
}
////////////////////////////////////////////////////////////////////////////////
template
void HMM::writeCurrEntropy ( FILE* pf, int f=-1 ) const {
if ( -1==f ) f=frameLast;
if ( 0<=f && f<=frameLast ) {
LogProb logh = 0.0;
LogProb logtop = 0.0;
for ( int i=0; i
void HMM::writeCurrDepths ( FILE* pf, int f=-1 ) const {
if ( -1==f ) f=frameLast;
if ( 0<=f && f<=frameLast ) {
LogProb sum = 0.0;
LogProb logtop = 0.0;
Array depths = Array();
Array logprobs = Array();
double avgdepth = 0.0;
for ( int i=0; i normprobs = Array();
Prob normprobsum = Prob();
for ( int i=0; i
void HMM::writeFollRanked ( FILE* pf, int f, int b, const typename MX::RandVarType& x, bool b1 ) const {
const TrellNode& tnsbPrev = aatnTrellis.get(f,b);
S sPrev = tnsbPrev.getId();
fprintf(pf,"from f=%04d b=%04d: ",f,b);
cout< >, outRank > ashpiQueue;
typedef quad > SHPI;
SHPI shpi, shpiTop;
int aCtr;
shpi.first = b;
shpi.third = tnsbPrev.getScore();
shpi.third *= my.setIterProb ( shpi.second, tnsbPrev.getId(), x, b1, aCtr=-1 );
shpi.fourth = 0;
ashpiQueue.enqueue(shpi);
//cerr<<"?? "<0; iTrg++ ) {
// Iterate A* (breadth-first) search until a complete path is at the top of the queue...
while ( ashpiQueue.getSize() > 0 && ashpiQueue.getTop().fourth < MY::IterVal::NUM_ITERS ) {
// Remove top...
shpiTop = ashpiQueue.dequeueTop();
// Fork off (try to advance each elementary variable a)...
for ( int a=shpiTop.fourth.toInt(); a<=MY::IterVal::NUM_ITERS; a++ ) {
// Copy top into new queue element...
shpi = shpiTop;
// At variable position -1, advance beam element for transition source...
if ( a == -1 ) shpi.first++;
// Incorporate prob from transition source...
shpi.third = aatnTrellis.get(f,shpi.first).getScore();
if ( shpi.third > LogProb() ) {
// Try to advance variable at position a and return probability (subsequent variables set to first, probability ignored)...
shpi.third *= my.setIterProb ( shpi.second, aatnTrellis.get(f,shpi.first).getId(), x, b1, aCtr=a );
// At end of variables, incorporate observation probability...
if ( a == MY::IterVal::NUM_ITERS && shpi.fourth != MY::IterVal::NUM_ITERS )
{ S s; my.setTrellDat(s,shpi.second); shpi.third *= mx.getProb(x,s); }
// Record variable position at which this element was forked off...
shpi.fourth = a;
////cerr<<" from partial: "< LogProb() ) {
cerr<<" "< 0 ) {
//cerr<
void HMM::writeFoll ( FILE* pf, int f, int b, const typename MX::RandVarType& o ) const {
const TrellNode& tnsbPrev = aatnTrellis.get(f,b);
S sPrev = tnsbPrev.getId();
fprintf(pf,"from f=%04d b=%04d: ",f,b);
cout<::writeFoll OUT OF ORDER\n";
/*
for ( bool b=my.setFirst(h,sPrev); b; b=my.setNext(h,sPrev) ) {
S s;
LogProb lgprO = mx.getProb(o,my.setTrellDat(s,h));
LogProb lgprH = my.getProb(h,sPrev);
LogProb lgprFull = tnsbPrev.getLogProb() * lgprH * lgprO;
cout<<" ==("< "<
int HMM::getBeamUsed ( int f=-1 ) const {
if ( -1==f ) f=frameLast;
int ctr=0;
if ( 0<=f && f<=frameLast )
for ( int i=0; i