EmissionSequence *HMM::sampleFromState(STATE q,int length) const { // Set up roulette wheels int nD=schema.getNumDiscrete(); Array1D<NmerChain*> chains(nD); Array1D<HigherOrderAlphabet> HOA(nD); for(int i=0 ; i<nD ; ++i) { HOA[i]=HigherOrderAlphabet(schema.getAlphabet(i),order+1); chains[i]=HOA[i].constructChain(); } Array2D< Array1D<RouletteWheel> > emitWheels(numStates,nD); for(STATE q=1 ; q<numStates ; ++q){ for(int i=0 ; i<nD ; ++i) { NmerChain &chain=*chains[i]; Array1D<RouletteWheel> &wheelArray=emitWheels[q][i]; Alphabet &alphabet=schema.getAlphabet(i); int radix=alphabet.size(); HigherOrderAlphabet &H=HOA[i]; int numNmers=H.size(); wheelArray.resize(numNmers); for(int nmer=0 ; nmer<numNmers ; ++nmer) { RouletteWheel &wheel=wheelArray[nmer]; for(int r=0 ; r<radix ; ++r) { // r iterations thu 0th order symbols NmerSymbol to=chain.nextNmer(nmer,r); // "to" is a higher order sym while(int(to)>=discreteEmitProb[q][i].size()) to=chain.getSuffix(to); wheel.addSector(exp(discreteEmitProb[q][i][to])); } wheel.doneAddingSectors(); } } } // Perform sampling EmissionSequence *seq=new EmissionSequence(schema); Array1D<Symbol> prevEmissions(nD); prevEmissions.setAllTo(0); // symbol 0 is always the empty string int len=0, nC=schema.getNumContinuous(); for(int j=0 ; j<length ; ++j) { Emission e; e.resize(nD,nC); emissionProb[q].sample(e.getContinuous()); for(int i=0 ; i<nD ; ++i) { NmerSymbol oldNmer=prevEmissions[i]; BaseSymbol s=emitWheels[q][i][oldNmer].spin(); NmerSymbol newNmer=chains[i]->nextNmer(oldNmer,s); e.getDiscrete(i)=newNmer; prevEmissions[i]=newNmer; } seq->append(e); ++len; } for(int i=0 ; i<nD ; ++i) delete chains[i]; // Return sampled sequence return seq; }
double HMM::getEmissionProb(int state,const Emission &x, bool omitContinuous) const { double P=omitContinuous || schema.getNumContinuous()==0 ? 0.0 : emissionProb[state].logDensity(x.getContinuous()); int numDiscrete=schema.getNumDiscrete(); for(int i=0 ; i<numDiscrete ; ++i) { const NmerChain &chain=chains[i]; NmerSymbol s=x.getDiscrete(i); const Array1D<double> &d=discreteEmitProb[state][i]; const int dsize=d.size(); while(int(s)>=dsize) s=chain.getSuffix(s); P+=d[s]; } return P; }