use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class NodeRetypeRandom method proposal.
@Override
public double proposal() {
double logHR = 0.0;
// Select node:
Node node;
do {
node = mtTree.getNode(Randomizer.nextInt(mtTree.getNodeCount()));
} while (node.isLeaf());
// Record probability of current types along attached branches:
if (!node.isRoot())
logHR += getBranchTypeProb(node);
logHR += getBranchTypeProb(node.getLeft()) + getBranchTypeProb(node.getRight());
// Select new node type:
((MultiTypeNode) node).setNodeType(Randomizer.nextInt(migModel.getNTypes()));
// Retype attached branches, forcing reject if inconsistent:
if (!node.isRoot()) {
logHR -= retypeBranch(node);
if (((MultiTypeNode) node).getFinalType() != ((MultiTypeNode) node.getParent()).getNodeType())
return Double.NEGATIVE_INFINITY;
}
logHR -= retypeBranch(node.getLeft()) + retypeBranch(node.getRight());
if ((((MultiTypeNode) node.getLeft()).getFinalType() != ((MultiTypeNode) node).getNodeType()) || (((MultiTypeNode) node.getRight()).getFinalType() != ((MultiTypeNode) node).getNodeType()))
return Double.NEGATIVE_INFINITY;
// WHY IS THIS NECESSARY!?
node.makeDirty(Tree.IS_DIRTY);
node.getLeft().makeDirty(Tree.IS_DIRTY);
node.getRight().makeDirty(Tree.IS_DIRTY);
return logHR;
}
use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class TypeMergeSplit method splitProposalRoot.
private double splitProposalRoot() {
Node root = mtTree.getRoot();
// Select new root type:
int oldType = ((MultiTypeNode) root).getNodeType();
int type;
do {
type = Randomizer.nextInt(migModel.getNTypes());
} while (type == oldType);
// Update node type:
((MultiTypeNode) root).setNodeType(type);
// Select new change times:
double tminLeft = ((MultiTypeNode) root.getLeft()).getFinalChangeTime();
double tnewLeft = (root.getHeight() - tminLeft) * Randomizer.nextDouble() + tminLeft;
double tminRight = ((MultiTypeNode) root.getRight()).getFinalChangeTime();
double tnewRight = (root.getHeight() - tminRight) * Randomizer.nextDouble() + tminRight;
// Add new changes below node:
((MultiTypeNode) root.getLeft()).addChange(type, tnewLeft);
((MultiTypeNode) root.getRight()).addChange(type, tnewRight);
return Math.log((root.getHeight() - tminRight) * (root.getHeight() - tminLeft) * (migModel.getNTypes() - 1));
}
use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class TypeBirthDeath method proposal.
@Override
public double proposal() {
// Immediate reject if <3 types in model
if (migModel.getNTypes() < 3)
return Double.NEGATIVE_INFINITY;
// Select event at random:
int event = Randomizer.nextInt(mtTree.getTotalNumberOfChanges() + mtTree.getInternalNodeCount() - 1);
MultiTypeNode node = null;
int changeIdx = -1;
if (event < mtTree.getInternalNodeCount() - 1)
node = (MultiTypeNode) mtTree.getNode(event + mtTree.getLeafNodeCount());
else {
event -= mtTree.getInternalNodeCount() - 1;
for (Node thisNode : mtTree.getNodesAsArray()) {
if (thisNode.isRoot())
continue;
if (event < ((MultiTypeNode) thisNode).getChangeCount()) {
node = (MultiTypeNode) thisNode;
changeIdx = event;
break;
}
event -= ((MultiTypeNode) thisNode).getChangeCount();
}
}
// Perform either birth or death move
if (Randomizer.nextBoolean())
return birthMove(node, changeIdx);
else
return deathMove(node, changeIdx);
}
use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class TypePairBirthDeath method proposal.
@Override
public double proposal() {
int n = mtTree.getLeafNodeCount();
int m = mtTree.getTotalNumberOfChanges();
// Select sub-edge at random:
int edgeNum = Randomizer.nextInt(2 * n - 2 + m);
// Find edge that sub-edge lies on:
Node selectedNode = null;
for (Node node : mtTree.getNodesAsArray()) {
if (node.isRoot())
continue;
if (edgeNum < ((MultiTypeNode) node).getChangeCount() + 1) {
selectedNode = node;
break;
}
edgeNum -= ((MultiTypeNode) node).getChangeCount() + 1;
}
// Complete either pair birth or pair death proposal:
if (Randomizer.nextDouble() < 0.5)
return birthProposal(selectedNode, edgeNum, n, m);
else
return deathProposal(selectedNode, edgeNum, n, m);
}
use of beast.evolution.tree.Node in project MultiTypeTree by tgvaughan.
the class TypedWilsonBalding method proposal.
@Override
public double proposal() {
// Check that operator can be applied to tree:
if (mtTree.getLeafNodeCount() < 3)
throw new IllegalStateException("Tree too small for" + " TypedWilsonBalding operator.");
// Select source node:
Node srcNode;
do {
srcNode = mtTree.getNode(Randomizer.nextInt(mtTree.getNodeCount()));
} while (invalidSrcNode(srcNode));
Node srcNodeP = srcNode.getParent();
Node srcNodeS = getOtherChild(srcNodeP, srcNode);
double t_srcNode = srcNode.getHeight();
double t_srcNodeP = srcNodeP.getHeight();
double t_srcNodeS = srcNodeS.getHeight();
// Select destination branch node:
Node destNode;
do {
destNode = mtTree.getNode(Randomizer.nextInt(mtTree.getNodeCount()));
} while (invalidDestNode(srcNode, destNode));
Node destNodeP = destNode.getParent();
double t_destNode = destNode.getHeight();
if (destNode.isRoot()) {
// FORWARD ROOT MOVE
double logHR = 0.0;
// Record probability of current colouring:
logHR += getBranchTypeProb(srcNode);
// Record srcNode grandmother height:
double t_srcNodeG = srcNodeP.getParent().getHeight();
// Choose new root height:
double newTime = t_destNode + Randomizer.nextExponential(1.0 / (alpha * t_destNode));
// Implement tree changes:
disconnectBranch(srcNode);
connectBranchToRoot(srcNode, destNode, newTime);
mtTree.setRoot(srcNodeP);
// Recolour root branches:
try {
logHR -= retypeRootBranches(srcNode);
} catch (NoValidPathException e) {
return Double.NEGATIVE_INFINITY;
}
// Return HR:
logHR += Math.log(alpha * t_destNode) + (1.0 / alpha) * (newTime / t_destNode - 1.0) - Math.log(t_srcNodeG - Math.max(t_srcNode, t_srcNodeS));
return logHR;
}
if (srcNodeP.isRoot()) {
// BACKWARD ROOT MOVE
double logHR = 0.0;
// Incorporate probability of current colouring:
logHR += getRootBranchTypeProb(srcNode);
// Record old srcNode parent height
double oldTime = t_srcNodeP;
// Choose height of new attachement point:
double min_newTime = Math.max(t_srcNode, t_destNode);
double t_destNodeP = destNodeP.getHeight();
double span = t_destNodeP - min_newTime;
double newTime = min_newTime + span * Randomizer.nextDouble();
// Implement tree changes:
disconnectBranchFromRoot(srcNode);
connectBranch(srcNode, destNode, newTime);
srcNodeS.setParent(null);
mtTree.setRoot(srcNodeS);
// Recolour new branch:
try {
logHR -= retypeBranch(srcNode);
} catch (NoValidPathException e) {
return Double.NEGATIVE_INFINITY;
}
// Return HR:
logHR += Math.log(t_destNodeP - Math.max(t_srcNode, t_destNode)) - Math.log(alpha * t_srcNodeS) - (1.0 / alpha) * (oldTime / t_srcNodeS - 1.0);
return logHR;
}
// NON-ROOT MOVE
double logHR = 0.0;
// Incorporate probability of current colouring.
logHR += getBranchTypeProb(srcNode);
// Record srcNode grandmother height:
double t_srcNodeG = srcNodeP.getParent().getHeight();
// Choose height of new attachment point:
double min_newTime = Math.max(t_destNode, t_srcNode);
double t_destNodeP = destNodeP.getHeight();
double span = t_destNodeP - min_newTime;
double newTime = min_newTime + span * Randomizer.nextDouble();
// Implement tree changes:
disconnectBranch(srcNode);
connectBranch(srcNode, destNode, newTime);
// Recolour new branch:
try {
logHR -= retypeBranch(srcNode);
} catch (NoValidPathException e) {
return Double.NEGATIVE_INFINITY;
}
// HR contribution of topology and node height changes:
logHR += Math.log(t_destNodeP - Math.max(t_srcNode, t_destNode)) - Math.log(t_srcNodeG - Math.max(t_srcNode, t_srcNodeS));
return logHR;
}
Aggregations