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