// This gives non-HW treatment of the 'F' term HMatrix makeHMatrixNHW( const PMF<Allele> &p, const PMF<Allele> &q, const BackFreq &hback, float delta, bool sparse) { // How much background to add in? // If the input HMatrix is not normalized then we make up the difference // with background. Otherwise we add in delta. double Bp = std::max((double)delta, 1 - p.sum()); // background for p double Bq = std::max((double)delta, 1 - q.sum()); // background for q // apply this formula: // H(ij) = p(i)q(j) + Bq p(i)b(j|i) + Bp (q(j)b(i|j) + Bp Bq Bij HMatrix ret; // loop over all elements in the background. This gives us the upper // triangular terms only. We need to sum over all terms. HMatrix &href = (HMatrix&)hback; // to use base class member PMF< std::pair<Allele, Allele> >::iterator it; for (it = href.m_pmf.begin(); it != href.m_pmf.end(); ++it) { Allele i = it->first.first; Allele j = it->first.second; double h_ij = term_ij(Bp, Bq, p, q, hback, i, j); // upper-triangular term if (i != j) { h_ij += term_ij(Bp, Bq, p, q, hback, j, i); // lower-triangular term } if (!sparse || h_ij > 0) ret.set(i, j, h_ij); } ret.normalize(); // just in case return ret; }
// construct PMF with the given background and delta, from a PMF representing the observed profile. // if pmf unknown (empty) return the background // NB The input PMF need NOT be normalized. The returned PMF is normalized. // static PMF<Allele> makePMF(const PMF<Allele> &pmf, const PMF<Allele> &background, float delta, bool sparse) { // How much background to add in? // If the input PMF is not normalized then we make up the difference // with background. Otherwise we add in delta. double bglevel = std::max((double)delta, 1 - pmf.sum()); PMF<Allele> ret; if (!sparse) { // This implementation ensures there is an element of the // returned PMF for each element of the background ret = background; if (! pmf.empty()) { ret *= bglevel; ret += pmf; ret.normalize(); } Assert2(ret.size() == background.size(), "PMF contains unknown alleles"); } else { // This implementation allows the PMF (and therefore the HMatrix) to remain sparse if (pmf.empty()) { ret = background; } else if (bglevel == 0) { ret = pmf; ret.normalize(); } else { ret = background; ret *= bglevel; ret += pmf; ret.normalize(); } } // cout << "pmf = " << pmf << endl; // cout << "background = " << background << endl; // cout << "bglevel = " << bglevel << endl; // cout << "ret = " << ret << endl << endl; return ret; }