use of beast.evolution.tree.MultiTypeNode in project MultiTypeTree by tgvaughan.
the class TypePairBirthDeath method deathProposal.
/**
* Colour change pair death proposal.
*
* @param node Node above which selected edge lies
* @param edgeNum Number of selected edge
* @param n Number of nodes on tree
* @param m Number of colour changes currently on tree
* @return log of Hastings factor of move.
*/
private double deathProposal(Node node, int edgeNum, int n, int m) {
MultiTypeNode mtNode = (MultiTypeNode) node;
int idx = edgeNum - 1;
int sidx = edgeNum - 2;
int ridx = edgeNum + 1;
if (sidx < -1 || ridx > mtNode.getChangeCount())
return Double.NEGATIVE_INFINITY;
double ts, tr;
int is, ir;
if (sidx < 0) {
ts = node.getHeight();
is = mtNode.getNodeType();
} else {
ts = mtNode.getChangeTime(sidx);
is = mtNode.getChangeType(sidx);
}
if (ridx > mtNode.getChangeCount() - 1)
tr = node.getParent().getHeight();
else
tr = mtNode.getChangeTime(ridx);
ir = mtNode.getChangeType(ridx - 1);
if (is != ir)
return Double.NEGATIVE_INFINITY;
mtNode.removeChange(idx);
mtNode.removeChange(idx);
return Math.log(2 * (m + 2 * n - 2)) - Math.log((migModel.getNTypes() - 1) * (m + 2 * n - 4) * (tr - ts) * (tr - ts));
}
use of beast.evolution.tree.MultiTypeNode 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.MultiTypeNode in project MultiTypeTree by tgvaughan.
the class TypedSubtreeExchangeRandom method proposal.
@Override
public double proposal() {
double logHR = 0.0;
// Select source and destination nodes:
Node srcNode, srcNodeParent, destNode, destNodeParent;
if (isNarrowInput.get()) {
// Narrow exchange selection:
do {
srcNode = mtTree.getNode(Randomizer.nextInt(mtTree.getNodeCount()));
} while (srcNode.isRoot() || srcNode.getParent().isRoot());
srcNodeParent = srcNode.getParent();
destNode = getOtherChild(srcNodeParent.getParent(), srcNodeParent);
destNodeParent = destNode.getParent();
} else {
// Wide exchange selection:
do {
srcNode = mtTree.getNode(Randomizer.nextInt(mtTree.getNodeCount()));
} while (srcNode.isRoot());
srcNodeParent = srcNode.getParent();
do {
destNode = mtTree.getNode(Randomizer.nextInt(mtTree.getNodeCount()));
} while (destNode == srcNode || destNode.isRoot() || destNode.getParent() == srcNode.getParent());
destNodeParent = destNode.getParent();
}
// lengths:
if (destNode.getHeight() > srcNodeParent.getHeight() || srcNode.getHeight() > destNodeParent.getHeight())
return Double.NEGATIVE_INFINITY;
// Record probability of old colours:
logHR += getBranchTypeProb(srcNode) + getBranchTypeProb(destNode);
// Make changes to tree topology:
replace(srcNodeParent, srcNode, destNode);
replace(destNodeParent, destNode, srcNode);
// Recolour branches involved:
logHR -= retypeBranch(srcNode) + retypeBranch(destNode);
// Force rejection if colouring inconsistent:
if ((((MultiTypeNode) srcNode).getFinalType() != ((MultiTypeNode) destNodeParent).getNodeType()) || (((MultiTypeNode) destNode).getFinalType() != ((MultiTypeNode) srcNodeParent).getNodeType()))
return Double.NEGATIVE_INFINITY;
return logHR;
}
use of beast.evolution.tree.MultiTypeNode in project MultiTypeTree by tgvaughan.
the class TypedWilsonBaldingEasy 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" + " ColouredWilsonBaldingRandom 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
// 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);
((MultiTypeNode) destNode).clearChanges();
connectBranchToRoot(srcNode, destNode, newTime);
mtTree.setRoot(srcNodeP);
// Abort if colouring inconsistent:
if (((MultiTypeNode) srcNode).getFinalType() != ((MultiTypeNode) destNode).getFinalType())
return Double.NEGATIVE_INFINITY;
// Update colour of root node:
((MultiTypeNode) srcNodeP).setNodeType(((MultiTypeNode) srcNode).getFinalType());
// Final test of tree validity:
if (!mtTree.isValid())
return Double.NEGATIVE_INFINITY;
// height changes:
return Math.log(alpha * t_destNode) + (1.0 / alpha) * (newTime / t_destNode - 1.0) - Math.log(t_srcNodeG - Math.max(t_srcNode, t_srcNodeS));
}
if (srcNodeP.isRoot()) {
// changes. (This would be an irreversible move.)
if (((MultiTypeNode) srcNodeS).getChangeCount() > 0 || (((MultiTypeNode) srcNodeS).getNodeType() != ((MultiTypeNode) srcNode).getFinalType()))
return Double.NEGATIVE_INFINITY;
// 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);
// Abort if new colouring is inconsistent:
if (((MultiTypeNode) srcNodeP).getNodeType() != ((MultiTypeNode) srcNode).getFinalType())
return Double.NEGATIVE_INFINITY;
// Final test of tree validity:
if (!mtTree.isValid())
return Double.NEGATIVE_INFINITY;
// height changes:
return Math.log(t_destNodeP - Math.max(t_srcNode, t_destNode)) - Math.log(alpha * t_srcNodeS) - (1.0 / alpha) * (oldTime / t_srcNodeS - 1.0);
}
// NON-ROOT MOVE
// 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);
// Reject outright if new colouring inconsistent:
if (((MultiTypeNode) srcNodeP).getNodeType() != ((MultiTypeNode) srcNode).getFinalType())
return Double.NEGATIVE_INFINITY;
// Final test of tree validity:
if (!mtTree.isValid())
return Double.NEGATIVE_INFINITY;
// height changes:
return Math.log(t_destNodeP - Math.max(t_srcNode, t_destNode)) - Math.log(t_srcNodeG - Math.max(t_srcNode, t_srcNodeS));
}
use of beast.evolution.tree.MultiTypeNode in project MultiTypeTree by tgvaughan.
the class BeerliFelsenstein method getPartialEventList.
/**
* Assemble and return list of events excluding those on the edge between
* node and its parent.
*
* @param excludedNode Tree node indicating edge to exclude.
* @return event list
*/
private List<Event> getPartialEventList(Node excludedNode) {
List<Event> eventList = Lists.newArrayList();
// Collect all events
for (Node node : mtTree.getNodesAsArray()) {
if (node == excludedNode)
continue;
MultiTypeNode mtNode = (MultiTypeNode) node;
Event event = new Event();
event.time = node.getHeight();
event.node = node;
event.thisDeme = mtNode.getNodeType();
if (node.isLeaf())
event.type = EventType.SAMPLE;
else {
if (!node.getChildren().contains(excludedNode))
event.type = EventType.COALESCENCE;
}
eventList.add(event);
int thisDeme = mtNode.getNodeType();
int prevDeme;
for (int i = 0; i < mtNode.getChangeCount(); i++) {
prevDeme = thisDeme;
thisDeme = mtNode.getChangeType(i);
Event changeEvent = new Event();
changeEvent.type = EventType.MIGRATION;
changeEvent.time = mtNode.getChangeTime(i);
changeEvent.node = node;
changeEvent.thisDeme = thisDeme;
changeEvent.prevDeme = prevDeme;
eventList.add(changeEvent);
}
}
// Sort events according to times
Collections.sort(eventList, new Comparator<Event>() {
@Override
public int compare(Event e1, Event e2) {
if (e1.time < e2.time)
return -1;
if (e1.time > e2.time)
return 1;
return 0;
}
});
return eventList;
}
Aggregations