/* Function: P7PriorifyHMM() * * Purpose: Add pseudocounts to an HMM using Dirichlet priors, * and renormalize the HMM. * * Args: hmm -- the HMM to add counts to (counts form) * pri -- the Dirichlet prior to use * * Return: (void) * HMM returns in probability form. */ void P7PriorifyHMM(struct plan7_s *hmm, struct p7prior_s *pri) { int k; /* counter for model position */ float d; /* a denominator */ /* Model-dependent transitions are handled simply; Laplace. */ FSet(hmm->begin+2, hmm->M-1, 0.); /* wipe internal BM entries */ FSet(hmm->end+1, hmm->M-1, 0.); /* wipe internal ME exits */ d = hmm->tbd1 + hmm->begin[1] + 2.; hmm->tbd1 = (hmm->tbd1 + 1.)/ d; hmm->begin[1] = (hmm->begin[1] + 1.)/ d; hmm->end[hmm->M] = 1.0; /* Main model transitions and emissions */ for (k = 1; k < hmm->M; k++) { P7PriorifyTransitionVector(hmm->t[k], pri); P7PriorifyEmissionVector(hmm->mat[k], pri, pri->mnum, pri->mq, pri->m, NULL); P7PriorifyEmissionVector(hmm->ins[k], pri, pri->inum, pri->iq, pri->i, NULL); } P7PriorifyEmissionVector(hmm->mat[hmm->M], pri, pri->mnum, pri->mq, pri->m, NULL); Plan7Renormalize(hmm); }
/* Function: P7PriorifyHMM() * * Purpose: Add pseudocounts to an HMM using Dirichlet priors, * and renormalize the HMM. * * Args: hmm -- the HMM to add counts to (counts form) * pri -- the Dirichlet prior to use * * Return: (void) * HMM returns in probability form. */ void P7PriorifyHMM(struct plan7_s *hmm, struct p7prior_s *pri) { int k; /* counter for model position */ float d; /* a denominator */ float tq[MAXDCHLET]; /* prior distribution over mixtures */ float mq[MAXDCHLET]; /* prior distribution over mixtures */ float iq[MAXDCHLET]; /* prior distribution over mixtures */ /* Model-dependent transitions are handled simply; Laplace. */ FSet(hmm->begin+2, hmm->M-1, 0.); /* wipe internal BM entries */ FSet(hmm->end+1, hmm->M-1, 0.); /* wipe internal ME exits */ d = hmm->tbd1 + hmm->begin[1] + 2.; hmm->tbd1 = (hmm->tbd1 + 1.)/ d; hmm->begin[1] = (hmm->begin[1] + 1.)/ d; hmm->end[hmm->M] = 1.0; /* Main model transitions and emissions */ for (k = 1; k < hmm->M; k++) { /* The following code chunk is experimental. * Collaboration with Michael Asman, Erik Sonnhammer, CGR Stockholm. * Only activated if X-PR* annotation has been used, in which * priors are overridden and a single Dirichlet component is * specified for each column (using structural annotation). * If X-PR* annotation is not used, which is usually the case, * the following code has no effect (observe how the real prior * distributions are copied into tq, mq, iq). */ if (hmm->tpri != NULL && hmm->tpri[k] >= 0) { if (hmm->tpri[k] >= pri->tnum) Die("X-PRT annotation out of range"); FSet(tq, pri->tnum, 0.0); tq[hmm->tpri[k]] = 1.0; } else FCopy(tq, pri->tq, pri->tnum); if (hmm->mpri != NULL && hmm->mpri[k] >= 0) { if (hmm->mpri[k] >= pri->mnum) Die("X-PRM annotation out of range"); FSet(mq, pri->mnum, 0.0); mq[hmm->mpri[k]] = 1.0; } else FCopy(mq, pri->mq, pri->mnum); if (hmm->ipri != NULL && hmm->ipri[k] >= 0) { if (hmm->ipri[k] >= pri->inum) Die("X-PRI annotation out of range"); FSet(iq, pri->inum, 0.0); iq[hmm->ipri[k]] = 1.0; } else FCopy(iq, pri->iq, pri->inum); /* This is the main line of the code: */ P7PriorifyTransitionVector(hmm->t[k], pri, tq); P7PriorifyEmissionVector(hmm->mat[k], pri, pri->mnum, mq, pri->m, NULL); P7PriorifyEmissionVector(hmm->ins[k], pri, pri->inum, iq, pri->i, NULL); } /* We repeat the above steps just for the final match state, M. */ if (hmm->mpri != NULL && hmm->mpri[hmm->M] >= 0) { if (hmm->mpri[hmm->M] >= pri->mnum) Die("X-PRM annotation out of range"); FSet(mq, pri->mnum, 0.0); mq[hmm->mpri[hmm->M]] = 1.0; } else FCopy(mq, pri->mq, pri->mnum); P7PriorifyEmissionVector(hmm->mat[hmm->M], pri, pri->mnum, mq, pri->m, NULL); /* Now we're done. Convert the counts-based HMM to probabilities. */ Plan7Renormalize(hmm); }