/** 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;
}
/** 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);
}