void AdmixtureEdgeReplaceResidualsFNPR::findNewBrothers(std::vector<AdmixtureNode *> &b, AdmixtureNode &p, AdmixtureNode *n) { if (&p != n) { size_t numChildren = n->getNumberOfChildren(); AdmixtureNode* child; for (size_t i = 0; i < numChildren; i++) { child = &n->getChild( i ); if ( child->getAge() < p.getAge() && child->getNumberOfChildren() != 1) { // && child != &q ) { b.push_back( child ); } else { findNewBrothers(b, p, child); } } } }
void AdmixtureShiftNodeAgeAndRate::rejectSimpleMove( void ) { // undo the ages storedNode->setAge( storedAge ); if (&storedNode->getAdmixtureParent() != NULL) storedNode->getAdmixtureParent().setAge( storedAge ); else if (&storedNode->getAdmixtureChild() != NULL) storedNode->getAdmixtureChild().setAge( storedAge ); // undo the rates branchRates[storedNode->getIndex()]->setValue(new double(storedRates[storedNode])); for (size_t i = 0; i < storedNode->getNumberOfChildren(); i++) { AdmixtureNode* ch = &storedNode->getTopologyChild(i); branchRates[ch->getIndex()]->setValue(new double(storedRates[ch])); } }
void AdmixtureEdgeReplaceResidualsFNPR::storeAdmixtureEventsForLineage(AdmixtureNode* p) { AdmixtureTree& tau = variable->getValue(); AdmixtureNode* q_it = &p->getParent(); while (q_it->getNumberOfChildren() == 1) { AdmixtureNode* qp = q_it; // adm parent if (&q_it->getAdmixtureChild() != NULL) ; // adm child else if (&q_it->getAdmixtureParent() != NULL) qp = &q_it->getAdmixtureParent(); // divergence else break; AdmixtureNode* qc = &qp->getAdmixtureChild(); AdmixtureNode* qpc = &qp->getChild(0); AdmixtureNode* qcc = &qc->getChild(0); //std::cout << "rem " << qp << " " << qc << " " << qpc << " " << qcc << "\n"; AdmixtureEdgePosition ap(qp, qc, qpc, qcc, qc->getAge(), qc->getWeight()); storedAdmixtureEdges.push_front(ap); tau.removeAdmixtureEdge(qp); tau.eraseAdmixtureNode(qp); tau.eraseAdmixtureNode(qc); q_it = &p->getParent(); } }
/** Perform the move */ double AdmixtureEdgeReplaceResidualWeights::performSimpleMove( void ) { // std::cout << "Admix Node Repl RW\n"; failed = false; failedAdd = false; // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; AdmixtureTree& tau = variable->getValue(); AdmixtureNode* root = &tau.getRoot(); size_t numTaxa = tau.getNumberOfTips(); std::vector<AdmixtureNode*> admixtureParents = tau.getAdmixtureParents(); // if no admixtureParent exists, the proposal fails if (admixtureParents.size() == 0) { failed = true; // std::cout << "no admixture evts\n"; return RbConstants::Double::neginf; } // otherwise, proceed else { storedResiduals = residuals->getValue(); // std::cout << "\nBEFORE\n"; // for (size_t i = 0; i < numTaxa; i++) // { // for (size_t j = 0; j < numTaxa; j++) // { // double r = storedResiduals[i * numTaxa + j]; // std::cout << r << " "; // } // std::cout << "\n"; // } // proposal densities // double fwdProposal = 1.0; // double bwdProposal = 1.0; failed = false; failedAdd = false; // sample a random admixture parent node double u = rng->uniform01(); size_t index = std::floor(admixtureParents.size() * u); // size_t numAdmixtureEdges = admixtureParents.size(); // store admixture edge position storedAdmixtureParent = admixtureParents[index]; storedAdmixtureChild = &storedAdmixtureParent->getAdmixtureChild(); storedAdmixtureChildParent = &storedAdmixtureChild->getParent(); storedAdmixtureChildChild = &storedAdmixtureChild->getChild(0); storedAdmixtureParentParent = &storedAdmixtureParent->getParent(); storedAdmixtureParentChild = &storedAdmixtureParent->getChild(0); // std::cout << "rem " << tau.getAdmixtureEdgeStr(storedAdmixtureParent, storedAdmixtureChild) << "\n"; // int oldChildBranchIdx = (int)storedAdmixtureChild->getTopologyChild(0).getIndex(); // int oldParentBranchIdx = (int)storedAdmixtureParent->getTopologyChild(0).getIndex(); // remove admixture edge from graph storedAdmixtureChild->removeChild(storedAdmixtureChildChild); storedAdmixtureChildChild->setParent(storedAdmixtureChildParent); storedAdmixtureChildParent->removeChild(storedAdmixtureChild); storedAdmixtureChildParent->addChild(storedAdmixtureChildChild); storedAdmixtureParent->removeChild(storedAdmixtureParentChild); storedAdmixtureParentChild->setParent(storedAdmixtureParentParent); storedAdmixtureParentParent->removeChild(storedAdmixtureParent); storedAdmixtureParentParent->addChild(storedAdmixtureParentChild); // get age for admixture event storedAdmixtureAge = storedAdmixtureChild->getAge(); storedAdmixtureWeight = storedAdmixtureChild->getWeight(); // initialize NA__ newAdmixtureChildChild = storedAdmixtureChildChild; newAdmixtureChildParent = storedAdmixtureChildParent; newAdmixtureParentChild = storedAdmixtureParentChild; newAdmixtureParentParent = storedAdmixtureParentParent; variable->touch(); // std::cout << "\nSAMPLE\n"; // storedResiduals = residuals->getValue(); // for (size_t i = 0; i < numTaxa; i++) // { // for (size_t j = 0; j < numTaxa; j++) // { // double r = storedResiduals[i * numTaxa + j]; // std::cout << r << " "; // } // std::cout << "\n"; // } //tau.checkAllEdgesRecursively(root); ////////////////////////////////////////////////// // add event ... //std::cout << "\n\treplace, add\n"; double maxStoredResidual = 0.0; for (size_t i = 0; i < storedResiduals.size(); i++) if (storedResiduals[i] > maxStoredResidual) maxStoredResidual = storedResiduals[i]; double lambda = delta / maxStoredResidual; //double lambda = 10.0; AdmixtureNode* nodeSrc = NULL; AdmixtureNode* nodeDst = NULL; size_t k_a = 0; size_t k_b = 0; // std::cout << "numTaxa\t" << numTaxa << "\n"; //double v = rng->uniform01(); // if (v < 0.5) // if (true) // { // get sum of positive residuals for each taxon against all other taxa std::vector<double> residualWeights_a(numTaxa,0.0); double sumResidualWeights_a = 0.0; for (size_t i = 0; i < numTaxa; i++) { for (size_t j = 0; j < numTaxa; j++) { double r = storedResiduals[i * numTaxa + j]; r = exp(lambda*r); if (r > 0.0 && i != j) //if (i != j) { residualWeights_a[i] += r; sumResidualWeights_a += r; } } } // if there are no positive residuals, abort move if (sumResidualWeights_a == 0.0) { // std::cout << "no pos residuals\n"; failedAdd = true; return RbConstants::Double::neginf; } // sample taxon A from weights double u_a = rng->uniform01() * sumResidualWeights_a; double m_a = 0.0; //size_t k_a = 0; for (size_t i = 0; i < numTaxa; i++) { m_a += residualWeights_a[i]; if (m_a > u_a) { k_a = i; nodeDst = &tau.getNode(k_a); break; } } //fwdProposal *= (residualWeights_a[k_a] / sumResidualWeights_a); // get sum of positive residuals for each taxon wrt taxon A std::vector<double> residualWeights_b(numTaxa,0.0); double sumResidualWeights_b = 0.0; for (size_t i = 0; i < numTaxa; i++) { double r = storedResiduals[k_a * numTaxa + i]; r = exp(lambda*r); if (r > 0.0 && k_a != i) //if (k_a != i) { residualWeights_b[i] += r; sumResidualWeights_b += r; } } // sample taxon B from weights double u_b = rng->uniform01() * sumResidualWeights_b; double m_b = 0.0; //size_t k_b = 0; for (size_t i = 0; i < numTaxa; i++) { m_b += residualWeights_b[i]; if (m_b > u_b) { k_b = i; nodeSrc = &tau.getNode(k_b); break; } } // // std::cout << "rw_a\t"; // for (size_t i = 0; i < numTaxa; i++) // std::cout << residualWeights_a[i] / sumResidualWeights_a << "\t"; // std::cout << "\n"; // std::cout << "pick " << k_a << " " << (residualWeights_a[k_a] / sumResidualWeights_a) << "\n"; // // // // std::cout << "rw_b\t"; // for (size_t i = 0; i < numTaxa; i++) // std::cout << residualWeights_b[i] / sumResidualWeights_b << "\t"; // std::cout << "\n"; // std::cout << "pick " << k_b << " " << (residualWeights_b[k_b] / sumResidualWeights_b) << "\n"; // //fwdProposal *= (residualWeights_b[k_b] / sumResidualWeights_b); // } // else // { // //std::cout << "random\n"; // k_a = rng->uniform01() * numTaxa; // do // { // k_b = rng->uniform01() * numTaxa; // } while(k_a == k_b); // nodeDst = &tau.getNode(k_a); // nodeSrc = &tau.getNode(k_b); // } // // std::cout << "taxa pair\t" << k_a << "\t" << k_b << "\n"; //std::cout << "fwdProposal\t" << fwdProposal << "\tlnFwdProposal\t" << log(fwdProposal) << "\n"; // get path from tip to root for both nodes AdmixtureNode* nd_a = nodeDst; std::list<AdmixtureNode*> path_a; // std::cout << "path_a : tip -> root\t" << nd_a << "\n"; while (nd_a != NULL) { // std::cout << "\t" << nd_a << "\t" << nd_a->getAge() << "\n"; path_a.push_back(nd_a); nd_a = &nd_a->getParent(); } nd_a = path_a.back(); AdmixtureNode* nd_b = nodeSrc; std::list<AdmixtureNode*> path_b; // std::cout << "path_b : tip -> root\t" << nd_b << "\n"; while (nd_b != NULL) { // std::cout << "\t" << nd_b << "\t" << nd_b->getAge() << "\n"; path_b.push_back(nd_b); nd_b = &nd_b->getParent(); } nd_b = path_b.back(); // find the node where the paths diverge by traversing both paths from root to tip AdmixtureNode* mrca = nd_a; // std::cout << "mrca : root -> tip\n"; while (nd_a == nd_b && !path_a.empty() && !path_b.empty()) { mrca = nd_a; // std::cout << "\t" << mrca << "\t" << mrca->getAge() << "\n"; nd_a = path_a.back(); nd_b = path_b.back(); path_a.pop_back(); path_b.pop_back(); } // sample u.a.r. between nd_b and present double minAge = nodeSrc->getAge(); if (minAge < nodeDst->getAge()) minAge = nodeDst->getAge(); double maxAge = mrca->getAge(); int mrcaChIdx = 0; // if (allowSisterAdmixture == false) // if (allowSisterAdmixture == false && mrca->getTopologyChild(0).isTip() == false && mrca->getTopologyChild(1).isTip() == false) if (allowSisterAdmixture == false)// && mrca->getTopologyChild(0).isTip() == false && mrca->getTopologyChild(1).isTip() == false) { maxAge = mrca->getTopologyChild(0).getAge(); if (maxAge < mrca->getTopologyChild(1).getAge()) { maxAge = mrca->getTopologyChild(1).getAge(); mrcaChIdx = 1; } } if (maxAge <= minAge) { // std::cout << "maxAge <= minAge\t" << maxAge << " < " << minAge << "\n"; failedAdd = true; return RbConstants::Double::neginf; } //maxAge = mrca->getAge(); //double admixtureAge = rng->uniform01() * (maxAge - minAge) + minAge; double exp_lambda = 2.0; double admixtureAge = RbStatistics::Beta::rv(1.0,exp_lambda, *rng) * (maxAge - minAge) + minAge; double a = 1.0; double b = 2.0; double admixtureWeight = RbStatistics::Beta::rv(a, b, *rng); //admixtureWeight /= 2; // attach edge as appropriate from aPath to bPath // front=0, back=1 // std::cout << "a_path : find admixtureAge\n"; while (nd_a->getAge() > admixtureAge && !path_a.empty()) { nd_a = path_a.back(); // std::cout << "\t" << nd_a << "\t" << nd_a->getAge() << "\n"; path_a.pop_back(); if (nd_a->getParent().getAge() > admixtureAge && nd_a->getAge() < admixtureAge) break; } // ... prob of selecting a certain source branch // double t_a = nd_a->getParent().getAge(); // fwdProposal *= t_a / (t_a - nodeSrc->getAge()); // std::cout << "b_path : find admixtureAge\n"; while (nd_b->getAge() > admixtureAge && !path_b.empty()) { nd_b = path_b.back(); // std::cout << "\t" << nd_b << "\t" << nd_b->getAge() << "\n"; path_b.pop_back(); if (nd_b->getParent().getAge() > admixtureAge && nd_b->getAge() < admixtureAge) break; } ////////////////////////////////////////////////// // placeholder for add // nd_a = storedAdmixtureParentChild; // nd_b = storedAdmixtureChildChild; double newAge = admixtureAge; double newWeight = admixtureWeight; //newWeight = storedAdmixtureWeight; // if (storedAdmixtureAge < maxAge && storedAdmixtureAge > minAge) // newAge = storedAdmixtureAge; // double newWeight = storedAdmixtureWeight; // std::cout << "age\t" << newAge << "\n"; // std::cout << "wt \t" << newWeight << "\n"; // add into graph if (rng->uniform01() < 0.5) { AdmixtureNode* tmp = nd_a; nd_a = nd_b; nd_b = tmp; } // store adjacent nodes to new parent node newAdmixtureParentChild = nd_a; newAdmixtureParentParent = &nd_a->getParent(); // insert admixtureParent into graph storedAdmixtureParent->setAge(newAge); storedAdmixtureParent->setParent(root); newAdmixtureParentChild->setParent(storedAdmixtureParent); newAdmixtureParentParent->addChild(storedAdmixtureParent); newAdmixtureParentParent->removeChild(newAdmixtureParentChild); // storedAdmixtureParent->addChild(newAdmixtureParentChild); storedAdmixtureParent->setParent(newAdmixtureParentParent); // store adjacent nodes to new child node newAdmixtureChildChild = nd_b; newAdmixtureChildParent = &nd_b->getParent(); // insert admixtureChild into graph storedAdmixtureChild->setAge(newAge); storedAdmixtureChild->setWeight(newWeight); storedAdmixtureChild->setParent(root); newAdmixtureChildChild->setParent(storedAdmixtureChild); newAdmixtureChildParent->addChild(storedAdmixtureChild); newAdmixtureChildParent->removeChild(newAdmixtureChildChild); storedAdmixtureChild->addChild(newAdmixtureChildChild); storedAdmixtureChild->setParent(newAdmixtureChildParent); // update with outgroup settings storedAdmixtureChild->setOutgroup(newAdmixtureChildChild->isOutgroup()); storedAdmixtureParent->setOutgroup(newAdmixtureParentChild->isOutgroup()); // std::cout << "add " << tau.getAdmixtureEdgeStr(storedAdmixtureParent, storedAdmixtureChild) << "\n"; // variable->touch(); // std::cout << "\nAFTER\n"; // storedResiduals = residuals->getValue(); // for (size_t i = 0; i < numTaxa; i++) // { // for (size_t j = 0; j < numTaxa; j++) // { // double r = storedResiduals[i * numTaxa + j]; // std::cout << r << " "; // } // std::cout << "\n"; // } // update branch rates //double lnBwdPropRates = 0.0; /* storedBranchRates.clear(); double delta = 0.0; // ... have oldBranchIdx already int newChildBranchIdx = (int)storedAdmixtureChild->getTopologyChild(0).getIndex(); int newParentBranchIdx = (int)storedAdmixtureParent->getTopologyChild(0).getIndex(); std::set<int> idxSet; idxSet.insert(oldChildBranchIdx); idxSet.insert(oldParentBranchIdx); idxSet.insert(newChildBranchIdx); idxSet.insert(newParentBranchIdx); //for (size_t i = 0; i < idxSet.size(); i++) for (std::set<int>::iterator it = idxSet.begin(); it != idxSet.end(); it++) { int idx = *it; double v = branchRates[idx]->getValue(); storedBranchRates[idx] = v; double u = exp(delta*(GLOBAL_RNG->uniform01() - 0.5)); branchRates[idx]->setValue(new double(u * v)); // std::cout << "br " << idx << " " << v << " -> " << u*v << "\n"; lnBwdPropRates += log(u); } // tau.checkAllEdgesRecursively(root); // ln hastings ratio //bwdProposal = 1.0 / numAdmixtureEdges; //fwdProposal = (residualWeights_a[k_a] / sumResidualWeights_a) * (residualWeights_b[k_b] / sumResidualWeights_b); double lnFwdProposal = log(fwdProposal); double lnBwdProposal = log(bwdProposal); */ return 0.0; } }
void AdmixtureBipartitionSummaryMonitor::updateBipartitions(void) { if (delayTimer->getValue() <= 0) { // get tree object AdmixtureTree* tau = &tree->getValue(); std::vector<AdmixtureNode*> nodes; for (unsigned i = 0; i < tree->getValue().getNumberOfNodes(); i++) nodes.push_back(&tau->getNode(i)); // map key iterator used for find() std::map<std::vector<bool>, std::vector<AdmixtureEdgeRecord> >::iterator it; // get partitions for all nodes bool firstRootHit = false; for (size_t i = 0; i < nodes.size(); i++) { AdmixtureNode* p = nodes[i]; if (p->isRoot()) continue; else if (&p->getParent() == &tau->getRoot() && firstRootHit) { firstRootHit = false; continue; } std::vector<bool> p_key = std::vector<bool>(numTaxa,false); std::vector<bool> c_key; AdmixtureEdgeRecord er(0,false,0,0,0,0); findTaxonBipartition(p_key, p); if (&p->getAdmixtureParent() != NULL) { // admixture children are handled by the admixture parent case continue; } else if (&p->getAdmixtureChild() == NULL && &p->getAdmixtureParent() == NULL) { // skip tips for tree partitions if (p->getNumberOfChildren() == 0) continue; // topology nodes have complementary disjoint bipartitions //flipTaxonBipartitionToMinor(p_key); er = AdmixtureEdgeRecord((int)numSamples,false,p->getWeight(),p->getAge(),p->getBranchLength(),branchRates->getValue()[p->getIndex()]); // if key exists, push on to existing value as copy of original node if (treeBipartitions.find(p_key) != treeBipartitions.end()) { treeBipartitions[p_key].push_back(er); //std::cout << "\tpush\n"; } // otherwise, create new vector else { std::vector<AdmixtureEdgeRecord> tmp(1,er); treeBipartitions[p_key] = tmp; //std::cout << "\tinsert\n"; } } else if (&p->getAdmixtureChild() != NULL) { // admixture parent-child pairs have disjoint bipartitions AdmixtureNode* c = &p->getAdmixtureChild(); c_key = std::vector<bool>(numTaxa,false); findTaxonBipartition(c_key, c); er = AdmixtureEdgeRecord((int)numSamples,true,c->getWeight(),c->getAge(),c->getBranchLength(),branchRates->getValue()[c->getTopologyChild(0).getIndex()]); // if key exists, push on to existing value as copy of original node if (AdmixtureBipartitionSummarys.find(p_key) != AdmixtureBipartitionSummarys.end() && AdmixtureBipartitionSummarys.at(p_key).find(c_key) != AdmixtureBipartitionSummarys.at(p_key).end()) { AdmixtureBipartitionSummarys[p_key][c_key].push_back(er); } // otherwise, create new vector else { std::vector<AdmixtureEdgeRecord> tmp(1,er); AdmixtureBipartitionSummarys[p_key][c_key] = tmp; } } } numSamples++; } }
/** Perform the move */ double AdmixtureShiftNodeAgeAndRate::performSimpleMove( void ) { failed = false; //std::cout << "\nAge-Rate Shift\n"; // clear old rates storedRates.clear(); // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; AdmixtureTree& tau = variable->getValue(); AdmixtureNode* node = &tau.getNode(nodeIndex); AdmixtureNode& parent = node->getParent(); // we need to work with the times double parent_age = parent.getAge(); double my_age = node->getAge(); double child_Age = node->getChild( 0 ).getAge(); if ( node->getNumberOfChildren() > 1 && child_Age < node->getChild( 1 ).getAge()) { child_Age = node->getChild( 1 ).getAge(); } // admixture node ages are further constrained by their partner's time if (&node->getAdmixtureChild() != NULL) { AdmixtureNode& admixtureChild = node->getAdmixtureChild(); double other_parent_age = admixtureChild.getParent().getAge(); if (parent_age > other_parent_age) parent_age = other_parent_age; double other_child_age = admixtureChild.getChild(0).getAge(); if (child_Age < other_child_age) child_Age = other_child_age; } else if (&node->getAdmixtureParent() != NULL) { AdmixtureNode& admixtureParent = node->getAdmixtureParent(); double other_parent_age = admixtureParent.getParent().getAge(); if (parent_age > other_parent_age) parent_age = other_parent_age; double other_child_age = admixtureParent.getChild(0).getAge(); if (child_Age < other_child_age) child_Age = other_child_age; } // now we store all necessary values storedNode = node; storedAge = my_age; // draw new age double ageRange = parent_age - child_Age; double unitAge = (storedAge - child_Age) / ageRange; double a = delta * unitAge + 1.0; double b = delta * (1.0 - unitAge) + 1.0; double newUnitAge = RbStatistics::Beta::rv(a, b, *rng); double fwdProposal = RbStatistics::Beta::lnPdf(a, b, newUnitAge); double my_new_age = newUnitAge * ageRange + child_Age; double new_a = delta * newUnitAge + 1.0; double new_b = delta * (1.0 - newUnitAge) + 1.0; double bwdProposal = RbStatistics::Beta::lnPdf(new_a, new_b, unitAge); // double get branch length double old_brlen = node->getTopologyParent().getAge() - my_age; double new_brlen = node->getTopologyParent().getAge() - my_new_age; double brlen_ratio = old_brlen / new_brlen; // update branch rate leading to node double node_rate = branchRates[node->getIndex()]->getValue(); //branchRates[node->getIndex()]->touch(); //std::cout << "br_name" << branchRates[node->getIndex()]->getName() << "\n"; storedRates[node] = node_rate; //std::cout << "brlen\t" << old_brlen << " -> " << new_brlen << " " << brlen_ratio << "\n"; //std::cout << "node_rate " << node_rate << " -> " << node_rate * brlen_ratio <<"\n"; node_rate = node_rate * brlen_ratio; branchRates[node->getIndex()]->setValue(new double(node_rate)); // update branch rates following from node for (size_t i = 0; i < storedNode->getNumberOfChildren(); i++) { AdmixtureNode* ch = &storedNode->getTopologyChild(i); //AdmixtureNode* ch = &storedNode->getChild(i); //double ch_ratio = (storedAge - ch->getAge()) / (my_new_age - ch->getAge()); double ch_ratio = (storedAge - ch->getAge()) / (my_new_age - ch->getAge()); double ch_rate = branchRates[ch->getIndex()]->getValue(); // branchRates[ch->getIndex()]->touch(); storedRates[ch] = ch_rate; //branchRates[node->getIndex()]->setValue(new double(ch_rate * ch_ratio)); //std::cout << "ch_brlen " << i << " " << (storedAge - ch->getAge()) << " -> " << (my_new_age - ch->getAge()) << " " << ch_ratio << "\n"; //std::cout << "ch_rate " << i << " " << ch_rate << " -> " << ch_rate * ch_ratio << "\n"; ch_rate = ch_rate * ch_ratio; branchRates[ch->getIndex()]->setValue(new double(ch_rate)); } // set the age node->setAge( my_new_age ); // set age of admixture partner if (&node->getAdmixtureParent() != NULL) node->getAdmixtureParent().setAge( my_new_age ); else if (&node->getAdmixtureChild() != NULL) node->getAdmixtureChild().setAge( my_new_age ); return bwdProposal - fwdProposal; }
std::string AdmixtureBipartitionMonitor::buildBipartitionString(void) { // return buffer std::stringstream ss; // get tree object AdmixtureTree* tau = &tree->getValue(); std::vector<AdmixtureNode*> nodes; for (unsigned i = 0; i < tree->getValue().getNumberOfNodes(); i++) nodes.push_back(&tau->getNode(i)); // bool firstRootHit = false; // necessary? for (size_t i = 0; i < nodes.size(); i++) { AdmixtureNode* p = nodes[i]; /* if (p->isRoot()) continue; else if (&p->getParent() == &tau->getRoot() && firstRootHit) { firstRootHit = false; continue; } */ std::vector<bool> pbp = std::vector<bool>(numTaxa,false); findTaxonBipartition(pbp, p); // look like s_0,s_1,r_0,r_1,t,w if (&p->getAdmixtureParent() != NULL) { // admixture children are handled by the admixture parent case continue; } else if (p->isRoot()) { for (size_t i = 0; i < pbp.size(); i++) { //std::cout << std::noboolalpha << pbp[i]; ss << std::noboolalpha << pbp[i]; } //std::cout << "\n"; ss << ","; ss << "," << p->getAge(); ss << ","; ss << ","; ss << ",1"; ss << separator; } else if (&p->getAdmixtureChild() == NULL && &p->getAdmixtureParent() == NULL) { // skip tips for divergence partitions // actually, keep 'em for pop-size params... //if (p->getNumberOfChildren() == 0) // continue; //ss << "D"; // print bitstring for divergence partition for (size_t i = 0; i < pbp.size(); i++) ss << std::noboolalpha << pbp[i]; ss << ","; ss << "," << p->getAge(); ss << "," << branchRates->getValue()[p->getIndex()]; ss << ","; ss << ",1"; ss << separator; } else if (&p->getAdmixtureChild() != NULL) { AdmixtureNode* c = &p->getAdmixtureChild(); std::vector<bool> cbp = std::vector<bool>(numTaxa,false); findTaxonBipartition(cbp, c); for (size_t i = 0; i < pbp.size(); i++) ss << std::noboolalpha << pbp[i]; ss << ","; for (size_t i = 0; i < cbp.size(); i++) ss << std::noboolalpha << cbp[i]; ss << "," << p->getAge(); ss << "," << branchRates->getValue()[p->getTopologyChild(0).getIndex()]; ss << "," << branchRates->getValue()[c->getTopologyChild(0).getIndex()]; ss << "," << c->getWeight(); ss << separator; } } return ss.str(); }
/** Perform the move */ double AdmixtureEdgeReplaceResidualsFNPR::performSimpleMove( void ) { storedAdmixtureEdges.clear(); newAdmixtureEdges.clear(); failed = false; numEvents = 0; AdmixtureTree& tau = variable->getValue(); // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; // stage FNPR pointers size_t numIntNodes = tau.getNumberOfInteriorNodes(); size_t numTaxa = tau.getNumberOfTips(); pruneNode = NULL; while (pruneNode == NULL || pruneNode == &tau.getRoot() || pruneNode->getNumberOfChildren() != 2) { pruneNode = &tau.getNode(rng->uniform01() * numIntNodes + numTaxa - 1); } pruneParent = &pruneNode->getParent(); // for (size_t i = 0; i < pruneParent->getNumberOfChildren(); i++) // std::cout << "\t" << &pruneParent->getChild(i) << "\n"; pruneChild = &pruneNode->getTopologyChild(rng->uniform01() * 2); // pruneNephew = &pruneNode->getChild(nphIdx); //std::cout << chIdx << " " << nphIdx << "\n"; // get regraft point std::vector<AdmixtureNode*> new_brothers; findNewBrothers(new_brothers, *pruneNode, &tau.getRoot()); int index = int(rng->uniform01() * new_brothers.size()); regraftChild = new_brothers[index]; if (pruneChild->isOutgroup() != regraftChild->isOutgroup()) { failed = true; return RbConstants::Double::neginf; } regraftParent = ®raftChild->getTopologyParent(); // std::cout << "\n"; // std::cout << "pch " << pruneChild << " <- " << &pruneChild->getTopologyParent() << "\n"; // //std::cout << "pnpw " << pruneNephew << " <- " << &pruneNephew->getTopologyParent() << "\n"; // // std::cout << "pnd " << pruneNode << " -> " << &pruneNode->getTopologyChild(chIdx) << " " << &pruneNode->getChild(nphIdx) << "\n"; // std::cout << "ppa " << pruneParent << " -> " << pruneNode << "\n"; // std::cout << "rch " << regraftChild << " <- " << ®raftChild->getTopologyParent() << "\n"; // std::cout << "rpa " << regraftParent << " -> " << ®raftParent->getTopologyChild(0) << " " << ®raftParent->getTopologyChild(1) << "\n"; // // std::cout << "\n"; // clear and store adm events on prune child lineage //std::cout << &pruneChild->getParent() << " " << ®raftChild->getParent() << " " << &pruneNephew->getParent() << "\n"; // for (size_t i = 0; i < pruneParent->getNumberOfChildren(); i++) // std::cout << "0\t" << &pruneParent->getChild(i) << "\n"; storeAdmixtureEventsForLineage(pruneChild); //std::cout << &pruneChild->getParent() << " " << ®raftChild->getParent() << " " << &pruneNephew->getParent() << "\n"; // for (size_t i = 0; i < pruneParent->getNumberOfChildren(); i++) // std::cout << "1\t" << &pruneParent->getChild(i) << "\n"; // clear and store adm events on regraft child lineage storeAdmixtureEventsForLineage(regraftChild); //std::cout << &pruneChild->getParent() << " " << ®raftChild->getParent() << " " << &pruneNephew->getParent() << "\n"; // for (size_t i = 0; i < pruneParent->getNumberOfChildren(); i++) // std::cout << "2\t" << &pruneParent->getChild(i) << "\n"; // perform FNPR //std::cout << "ppa " << pruneParent << " -> " << &pruneParent->getChild(0) << " " << &pruneParent->getChild(1) << " " << &pruneNode->getParent() << "\n"; int nphIdx = 0; if (pruneChild == &pruneNode->getTopologyChild(nphIdx)) nphIdx = 1; pruneNephew = &pruneNode->getChild(nphIdx); pruneParent = &pruneNode->getParent(); // std::cout << &pruneChild->getParent() << " " << ®raftChild->getParent() << " " << &pruneNephew->getParent() << "\n"; // std::cout << "ppa " << pruneParent << " -> " << pruneNode << "\n"; // for (size_t i = 0; i < pruneParent->getNumberOfChildren(); i++) // std::cout << "\t" << &pruneParent->getChild(i) << "\n"; pruneParent->removeChild(pruneNode,false); pruneNode->removeChild(pruneNephew,false); pruneParent->addChild(pruneNephew,false); pruneNephew->setParent(pruneParent,false); regraftParent->removeChild(regraftChild,false); regraftParent->addChild(pruneNode,false); pruneNode->addChild(regraftChild,false); pruneNode->setParent(regraftParent,false); pruneNode->setOutgroup(regraftChild->isOutgroup()); regraftChild->setParent(pruneNode,false); // get new age double maxRegraftAge = regraftParent->getAge(); double minRegraftAge = regraftChild->getAge(); if (minRegraftAge < pruneChild->getAge()) minRegraftAge = pruneChild->getAge(); storedPruneAge = pruneNode->getAge(); double newPruneAge = rng->uniform01() * (maxRegraftAge - minRegraftAge) + minRegraftAge; pruneNode->setAge(newPruneAge); // draw new admixture edges //double fwdProposal = 1.0; //int numEvents = storedAdmixtureEdges.size(); for (unsigned i = 0; i < storedAdmixtureEdges.size(); i++) { residuals->touch(); storedResiduals = residuals->getValue(); size_t numTaxa = tau.getNumberOfTips(); AdmixtureNode* nodeSrc = NULL; AdmixtureNode* nodeDst = NULL; size_t k_a = 0; size_t k_b = 0; /* if (tau.getNumberOfAdmixtureParents() >= maxEvents) { failed = true; return RbConstants::Double::neginf; } */ double maxStoredResidual = 0.0; for (size_t i = 0; i < storedResiduals.size(); i++) if (storedResiduals[i] > maxStoredResidual) maxStoredResidual = storedResiduals[i]; double lambda = delta / maxStoredResidual; // get sum of positive residuals for each taxon against all other taxa std::vector<double> residualWeights_a(numTaxa,0.0); double sumResidualWeights_a = 0.0; for (size_t i = 0; i < numTaxa; i++) { for (size_t j = 0; j < numTaxa; j++) { double r = storedResiduals[i * numTaxa + j]; r = exp(lambda*r); if (r > 0.0 && i != j) //if (i != j) { residualWeights_a[i] += r; sumResidualWeights_a += r; } } } // if there are no positive residuals, abort move if (sumResidualWeights_a == 0.0) { //std::cout << "no pos residuals\n"; failed = true; return RbConstants::Double::neginf; } // std::cout << "rw_a\t"; // for (size_t i = 0; i < numTaxa; i++) // std::cout << residualWeights_a[i] / sumResidualWeights_a << "\t"; // std::cout << "\n"; // sample taxon A from weights double u_a = rng->uniform01() * sumResidualWeights_a; double m_a = 0.0; //size_t k_a = 0; for (size_t i = 0; i < numTaxa; i++) { m_a += residualWeights_a[i]; if (m_a > u_a) { k_a = i; nodeDst = &tau.getNode(k_a); break; } } //std::cout << "pick " << k_a << "\n"; //fwdProposal *= (residualWeights_a[k_a] / sumResidualWeights_a); // get sum of positive residuals for each taxon wrt taxon A std::vector<double> residualWeights_b(numTaxa,0.0); double sumResidualWeights_b = 0.0; for (size_t i = 0; i < numTaxa; i++) { double r = storedResiduals[k_a * numTaxa + i]; r = exp(lambda*r); if (r > 0.0 && k_a != i) //if (k_a != i) { residualWeights_b[i] += r; sumResidualWeights_b += r; } } // std::cout << "rw_b\t"; // for (size_t i = 0; i < numTaxa; i++) // std::cout << residualWeights_b[i] / sumResidualWeights_b << "\t"; // std::cout << "\n"; // sample taxon B from weights double u_b = rng->uniform01() * sumResidualWeights_b; double m_b = 0.0; //size_t k_b = 0; for (size_t i = 0; i < numTaxa; i++) { m_b += residualWeights_b[i]; if (m_b > u_b) { k_b = i; nodeSrc = &tau.getNode(k_b); break; } } // std::cout << "pick " << k_b << "\n\n"; //fwdProposal *= (residualWeights_b[k_b] / sumResidualWeights_b); // get path from tip to root for both nodes AdmixtureNode* nd_a = nodeSrc; std::list<AdmixtureNode*> path_a; //std::cout << "path_a : tip -> root\n"; while (nd_a != NULL) { //std::cout << "\tnd_a\t" << nd_a->getIndex() << "\t" << nd_a << "\t" << nd_a->getAge() << "\t" << &nd_a->getParent() << "\n"; path_a.push_back(nd_a); nd_a = &nd_a->getParent(); } nd_a = path_a.back(); AdmixtureNode* nd_b = nodeDst; std::list<AdmixtureNode*> path_b; //std::cout << "path_b : tip -> root\n"; while (nd_b != NULL) { //std::cout << "\tnd_b\t" << nd_b->getIndex() << "\t" << nd_b << "\t" << nd_b->getAge() << "\n"; path_b.push_back(nd_b); nd_b = &nd_b->getParent(); } nd_b = path_b.back(); // find the node where the paths diverge by traversing both paths from root to tip AdmixtureNode* mrca = nd_a; //std::cout << "mrca : root -> tip\n"; while (nd_a == nd_b && !path_a.empty() && !path_b.empty()) { mrca = nd_a; // std::cout << "\t" << mrca << "\t" << mrca->getAge() << "\n"; nd_a = path_a.back(); nd_b = path_b.back(); path_a.pop_back(); path_b.pop_back(); } // sample u.a.r. between nd_b and present (we disallow sister branches to admix...) double minAge = nodeSrc->getAge(); if (minAge < nodeDst->getAge()) minAge = nodeDst->getAge(); double maxAge = mrca->getAge(); int mrcaChIdx = 0; if (allowSisterAdmixture == false)// && mrca->getTopologyChild(0).isTip() == false && mrca->getTopologyChild(1).isTip() == false) { maxAge = mrca->getTopologyChild(0).getAge(); if (maxAge < mrca->getTopologyChild(1).getAge()) { maxAge = mrca->getTopologyChild(1).getAge(); mrcaChIdx = 1; } } if (maxAge <= minAge) { failed = true; return RbConstants::Double::neginf; } //maxAge = mrca->getAge(); //double admixtureAge = rng->uniform01() * (maxAge - minAge) + minAge; double exp_lambda = 2.0; double admixtureAge = RbStatistics::Beta::rv(1.0,exp_lambda, *rng) * (maxAge - minAge) + minAge; while (nd_a->getAge() > admixtureAge && !path_a.empty()) { nd_a = path_a.back(); path_a.pop_back(); if (nd_a->getParent().getAge() > admixtureAge && nd_a->getAge() < admixtureAge) break; } while (nd_b->getAge() > admixtureAge && !path_b.empty()) { nd_b = path_b.back(); path_b.pop_back(); if (nd_b->getParent().getAge() > admixtureAge && nd_b->getAge() < admixtureAge) break; } if (GLOBAL_RNG->uniform01() < 0.5) { AdmixtureNode* tmp = nd_a; nd_a = nd_b; nd_b = tmp; } //std::cout << "ok\n"; // get admixture weight double a = 1.0; double b = 2.0; double admixtureWeight = RbStatistics::Beta::rv(a, b, *rng); //double lnW = 0.0; admixtureWeight /= 2; // add nodes to tree AdmixtureNode* storedAdmixtureParent = new AdmixtureNode((int)tau.getNumberOfNodes()); tau.pushAdmixtureNode(storedAdmixtureParent); AdmixtureNode* storedAdmixtureChild = new AdmixtureNode((int)tau.getNumberOfNodes()); tau.pushAdmixtureNode(storedAdmixtureChild); // add edge tau.addAdmixtureEdge(storedAdmixtureParent, storedAdmixtureChild, nd_a, nd_b, admixtureAge, admixtureWeight, true); AdmixtureEdgePosition ap(storedAdmixtureParent, storedAdmixtureChild, nd_a, nd_b, admixtureAge, admixtureWeight); newAdmixtureEdges.push_front(ap); } tau.getRoot().flagNewickRecomputation(); return 0.0; }
/** Perform the move */ double AdmixtureEdgeRemoveResidualWeights::performSimpleMove( void ) { //std::cout << "\nAdmix Node Rem RW\n"; // Get random number generator failed = false; RandomNumberGenerator* rng = GLOBAL_RNG; AdmixtureTree& tau = variable->getValue(); std::vector<AdmixtureNode*> admixtureParents = tau.getAdmixtureParents(); // if no admixtureParent exists, the proposal fails if (admixtureParents.size() == 0) { failed = true; return RbConstants::Double::neginf; } // otherwise, proceed else { failed = false; // sample a random admixture parent node double u = rng->uniform01(); size_t index = std::floor(admixtureParents.size() * u); AdmixtureNode* admixtureParent = admixtureParents[index]; AdmixtureNode* admixtureChild = &admixtureParent->getAdmixtureChild(); //double w = admixtureChild->getWeight(); // get all nodes adjacent to proposal storedAdmixtureChild = admixtureChild; storedAdmixtureChildChild = &admixtureChild->getChild(0); storedAdmixtureChildParent = &admixtureChild->getParent(); storedAdmixtureParent = admixtureParent; storedAdmixtureParentChild = &admixtureParent->getChild(0); storedAdmixtureParentParent = &admixtureParent->getParent(); // update edges to remove admixtureChild in graph storedAdmixtureChildChild->setParent(storedAdmixtureChildParent); storedAdmixtureChildParent->removeChild(admixtureChild); storedAdmixtureChildParent->addChild(storedAdmixtureChildChild); // update edges to remove admixtureParent in graph storedAdmixtureParentParent->removeChild(admixtureParent); storedAdmixtureParentParent->addChild(storedAdmixtureParentChild); storedAdmixtureParentChild->setParent(storedAdmixtureParentParent); /* // get set of tips descendant from AC and AP //std::cout << "tips_ap\n"; std::set<AdmixtureNode*> tips_ap; findDescendantTips(tips_ap, storedAdmixtureParent); //std::cout << "tips_ac\n"; std::set<AdmixtureNode*> tips_ac; findDescendantTips(tips_ac, storedAdmixtureChild); */ // remove nodes from admixtureTree vector tau.eraseAdmixtureNode(storedAdmixtureParent); tau.eraseAdmixtureNode(storedAdmixtureChild); // get sum of positive residuals for each taxon against all other taxa storedResiduals = residuals->getValue(); size_t numTaxa = tau.getNumberOfTips(); double bwdProposal = 0.0; double maxStoredResidual = 0.0; for (size_t i = 0; i < storedResiduals.size(); i++) if (storedResiduals[i] > maxStoredResidual) maxStoredResidual = storedResiduals[i]; double lambda = delta / maxStoredResidual; // get sum of positive residuals for each taxon against all other taxa std::vector<double> residualWeights_a(numTaxa,0.0); double sumResidualWeights_a = 0.0; for (size_t i = 0; i < numTaxa; i++) { for (size_t j = 0; j < numTaxa; j++) { double r = storedResiduals[i * numTaxa + j]; r = exp(lambda*r); if (r > 0.0 && i != j) //if (i != j) { residualWeights_a[i] += r; sumResidualWeights_a += r; } } } size_t k_a = admixtureParent->getIndex(); bwdProposal *= (residualWeights_a[k_a] / sumResidualWeights_a); // get sum of positive residuals for each taxon wrt taxon A std::vector<double> residualWeights_b(numTaxa,0.0); double sumResidualWeights_b = 0.0; for (size_t i = 0; i < numTaxa; i++) { double r = storedResiduals[k_a * numTaxa + i]; r = exp(lambda*r); if (r > 0.0 && k_a != i) //if (k_a != i) { residualWeights_b[i] += r; sumResidualWeights_b += r; } } size_t k_b = admixtureChild->getIndex(); bwdProposal *= (residualWeights_b[k_b] / sumResidualWeights_b); // prior & propsal admixture weights cancel... //double lnW = 0.0; // prior * proposal ratio numEvents = (int)tau.getNumberOfAdmixtureChildren(); admixtureCount->setValue(new int(numEvents)); return 0.0; //double lnFwdProposal = -log(numEvents+1); //return lnW + log(bwdProposal) - lnFwdProposal; } }
/* Build newick string */ std::string ExtendedNewickAdmixtureTreeMonitor::buildExtendedNewick( AdmixtureNode* n ) { // create the newick string std::stringstream o; // extended data is only found on admixture nodes std::string additionalInfo = ""; // loop over admixture nodes per branch std::stringstream admixturestream; double br = 1.0; if (!n->isRoot()) { if (showRates) br = branchRates->getValue()[n->getIndex()]; //std::cout << "hmm\n"; // [{s=&srcPtr,d=&dstPtr,t=double,w=double},{...},...,{...}] if (showMetadata) { admixturestream << "["; AdmixtureNode* p = &n->getParent(); while (p->getNumberOfChildren() == 1) { // std::cout << "ok\n"; admixturestream << "{s="; if (&p->getAdmixtureParent() == NULL) admixturestream << p; else admixturestream << &p->getAdmixtureParent(); admixturestream << ",d="; if (&p->getAdmixtureChild() == NULL) admixturestream << p; else admixturestream << &p->getAdmixtureChild(); admixturestream << ",t=" << p->getAge(); admixturestream << ",w=" << p->getWeight(); admixturestream << "}"; p = &p->getParent(); if (p->getNumberOfChildren() == 1) admixturestream << ","; } admixturestream << "]"; additionalInfo = admixturestream.str(); } } // std::cout << br << "\n"; //std::cout << additionalInfo << "\n"; // test whether this is a internal or external node if (n->isTip()) { //std::cout << "tipnode\t" << additionalInfo << "\n"; // this is a tip so we just return the name of the node o << n->getName() << additionalInfo << ":" << n->getTopologyBranchLength() * br; } else { //std::cout << "intnode\t" << additionalInfo << "\n"; o << "("; for (size_t i=0; i<(n->getNumberOfChildren()-1); i++) { o << buildExtendedNewick( &n->getTopologyChild(i) ) << ","; } o << buildExtendedNewick( &n->getTopologyChild(n->getNumberOfChildren()-1) ) << ")" << additionalInfo << ":" << n->getTopologyBranchLength() * br; } return o.str(); }
/** Perform the move */ double AdmixtureNearestNeighborInterchangeAndRateShift::performSimpleMove( void ) { //std::cout << "\nDiv Node NNI & Rate Rescale\n"; failed = false; // Get random number generator RandomNumberGenerator* rng = GLOBAL_RNG; AdmixtureTree& tau = variable->getValue(); // pick a random node which is not the root and neithor the direct descendant of the root AdmixtureNode* node; do { double u = rng->uniform01(); size_t index = std::floor(tau.getNumberOfNodes() * u); node = &tau.getNode(index); } while ( node->isRoot() || node->getTopologyParent().isRoot() || node->getNumberOfChildren() != 2); int nodeChildMoveIdx = (int)std::floor(rng->uniform01() * 2.0); int nodeBrotherIdx = 0; //std::cout << "nodeChildeMoveIdx " << nodeChildMoveIdx << "\n"; // divergence location AdmixtureNode* childMove = &node->getChild(nodeChildMoveIdx); AdmixtureNode* parent = &node->getTopologyParent(); AdmixtureNode* brother = &parent->getTopologyChild( nodeBrotherIdx ); // check if we got the correct child lineage if ( brother == node ) { if (nodeBrotherIdx == 0) nodeBrotherIdx = 1; else nodeBrotherIdx = 0; } // get brother of node (not divergence child node) brother = &parent->getChild(nodeBrotherIdx); if (brother->getAge() > node->getAge()) { //std::cout << "failed, bro > node\n"; failed = true; return RbConstants::Double::neginf; } else if (childMove->getAge() > parent->getAge()) { //std::cout << "failed, child > parent\n"; failed = true; return RbConstants::Double::neginf; } else if (childMove->isOutgroup() != brother->isOutgroup()) { //std::cout << "failed, outgroup mismatch\n"; failed = true; return RbConstants::Double::neginf; } // update parent clade storedNodeParent = parent; storedNodeChildMove = childMove; storedBrother = brother; storedNode = node; // swap storedNode->removeChild(storedNodeChildMove); storedNodeParent->removeChild(storedBrother); storedNode->addChild(storedBrother); storedNodeParent->addChild(storedNodeChildMove); storedBrother->setParent(storedNode); storedNodeChildMove->setParent(storedNodeParent); // get branch rate index storedChildRateIndex = (int)node->getTopologyChild(nodeChildMoveIdx).getIndex(); storedBrotherRateIndex = (int)parent->getTopologyChild(nodeBrotherIdx).getIndex(); // storedNodeRateIndex = node->getIndex(); // store branch rate values storedChildRate = branchRates[storedChildRateIndex]->getValue(); // storedNodeRate = branchRates[storedNodeRateIndex]->getValue(); storedBrotherRate = branchRates[storedBrotherRateIndex]->getValue(); // update //double cnr = 0.0; //double snr = 0.0; //double sbr = 0.0; double scaleChildRate = exp(delta*(rng->uniform01() - 0.5)); // double scaleNodeRate = exp(delta*(rng->uniform01() - 0.5)); double scaleBrotherRate = exp(delta*(rng->uniform01() - 0.5)); branchRates[storedChildRateIndex]->setValue(new double(storedChildRate*scaleChildRate)); // branchRates[storedNodeRateIndex]->setValue(new double(storedNodeRate * scaleNodeRate)); branchRates[storedBrotherRateIndex]->setValue(new double(storedBrotherRate * scaleBrotherRate)); //branchRates[storedChildRateIndex]->touch(); //std::cout << "chld rate " << storedChildRate << " -> " << storedChildRate*scaleChildRate << "\n"; // std::cout << "node rate " << storedNodeRate << " -> " << storedNodeRate*scaleNodeRate << "\n"; //std::cout << "bro rate " << storedBrotherRate << " -> " << storedBrotherRate*scaleBrotherRate << "\n"; if (storedChildRate * scaleChildRate == 0.0) { ;//std::cout << "new scaledChildRate == 0.0\n"; } //if (storedNodeRate * scaleNodeRate == 0.0) //{ // std::cout << "new scaledNodeRate == 0.0\n"; //} if (storedBrotherRate * scaleBrotherRate == 0.0) { ;//std::cout << "new scaledBrotherRate == 0.0\n"; } //std::cout << scaleChildRate*scaleBrotherRate << " " << log(scaleChildRate*scaleBrotherRate) << "\n"; // MH // return 0.0; return log(scaleChildRate*scaleBrotherRate); }