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(); }
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 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); }