/* Evaluate fx = rel entropy - etarget, which we want to be = 0, * for effective sequence number <x>. */ static int eweight_target_f(double Neff, void *params, double *ret_fx) { struct ew_param_s *p = (struct ew_param_s *) params; p7_hmm_CopyParameters(p->hmm, p->h2); p7_hmm_Scale(p->h2, Neff / (double) p->h2->nseq); p7_ParameterEstimation(p->h2, p->pri); *ret_fx = p7_MeanMatchRelativeEntropy(p->h2, p->bg) - p->etarget; return eslOK; }
/* set_effective_seqnumber() * * <hmm> comes in with weighted observed counts. It goes out with * those observed counts rescaled to sum to the "effective sequence * number". * * <msa> is needed because we may need to see the sequences in order * to determine effective seq #. (for --eclust) * * <prior> is needed because we may need to parameterize test models * looking for the right relative entropy. (for --eent, the default) */ static int effective_seqnumber(P7_BUILDER *bld, const ESL_MSA *msa, P7_HMM *hmm, const P7_BG *bg) { int status; if (bld->effn_strategy == p7_EFFN_NONE) hmm->eff_nseq = msa->nseq; else if (bld->effn_strategy == p7_EFFN_SET) hmm->eff_nseq = bld->eset; else if (bld->effn_strategy == p7_EFFN_CLUST) { int nclust; status = esl_msacluster_SingleLinkage(msa, bld->eid, NULL, NULL, &nclust); if (status == eslEMEM) ESL_XFAIL(status, bld->errbuf, "memory allocation failed"); else if (status != eslOK) ESL_XFAIL(status, bld->errbuf, "single linkage clustering algorithm (at %d%% id) failed", (int)(100 * bld->eid)); hmm->eff_nseq = (double) nclust; } else if (bld->effn_strategy == p7_EFFN_ENTROPY) { double etarget; double eff_nseq; etarget = (bld->esigma - eslCONST_LOG2R * log( 2.0 / ((double) hmm->M * (double) (hmm->M+1)))) / (double) hmm->M; /* xref J5/36. */ etarget = ESL_MAX(bld->re_target, etarget); status = p7_EntropyWeight(hmm, bg, bld->prior, etarget, &eff_nseq); if (status == eslEMEM) ESL_XFAIL(status, bld->errbuf, "memory allocation failed"); else if (status != eslOK) ESL_XFAIL(status, bld->errbuf, "internal failure in entropy weighting algorithm"); hmm->eff_nseq = eff_nseq; } p7_hmm_Scale(hmm, hmm->eff_nseq / (double) hmm->nseq); return eslOK; ERROR: return status; }