use of beast.evolution.tree.MultiTypeNode 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.MultiTypeNode in project MultiTypeTree by tgvaughan.
the class SpecialTypeBirthDeath method proposal.
@Override
public double proposal() {
if (mtTree.getLeafNodeCount() != 2)
throw new IllegalArgumentException("SpecialTypeBirthDeath only valid for 2 taxon trees.");
// Cannot produce or operate on trees without any changes
if (mtTree.getTotalNumberOfChanges() == 0)
return Double.NEGATIVE_INFINITY;
// String startTree = mtTree.toString();
MultiTypeNode root = (MultiTypeNode) mtTree.getRoot();
MultiTypeNode left = (MultiTypeNode) root.getLeft();
MultiTypeNode right = (MultiTypeNode) root.getRight();
// Select event:
int event = Randomizer.nextInt(mtTree.getTotalNumberOfChanges());
MultiTypeNode node, sister;
int changeIdx;
if (event < left.getChangeCount()) {
node = left;
sister = right;
changeIdx = event;
} else {
node = right;
sister = left;
changeIdx = event - left.getChangeCount();
}
// Implement birth or death
double logHR;
boolean birth = Randomizer.nextBoolean();
if (birth)
logHR = birthProposal(node, changeIdx, sister);
else
logHR = deathProposal(node, changeIdx, sister);
return logHR;
}
use of beast.evolution.tree.MultiTypeNode in project MultiTypeTree by tgvaughan.
the class TypeMergeSplit method mergeProposal.
/**
* Remove a pair of migrations below a coalescence event and create
* one above it.
*
* @param node Node representing coalescence event.
* @return log of Hastings ratio
*/
private double mergeProposal(Node node) {
MultiTypeNode left = (MultiTypeNode) node.getLeft();
MultiTypeNode right = (MultiTypeNode) node.getRight();
MultiTypeNode mtNode = (MultiTypeNode) node;
int leftIdx = left.getChangeCount() - 1;
int rightIdx = right.getChangeCount() - 1;
if (leftIdx < 0 || rightIdx < 0)
return Double.NEGATIVE_INFINITY;
int leftType = left.getChangeType(leftIdx);
int rightType = right.getChangeType(rightIdx);
if (leftType != rightType)
return Double.NEGATIVE_INFINITY;
int leftTypeUnder;
double tminLeft;
if (leftIdx > 0) {
leftTypeUnder = left.getChangeType(leftIdx - 1);
tminLeft = left.getChangeTime(leftIdx - 1);
} else {
leftTypeUnder = left.getNodeType();
tminLeft = left.getHeight();
}
int rightTypeUnder;
double tminRight;
if (rightIdx > 0) {
rightTypeUnder = right.getChangeType(rightIdx - 1);
tminRight = right.getChangeTime(rightIdx - 1);
} else {
rightTypeUnder = right.getNodeType();
tminRight = right.getHeight();
}
if (leftTypeUnder != rightTypeUnder)
return Double.NEGATIVE_INFINITY;
double tmax;
if (mtNode.getChangeCount() > 0)
tmax = mtNode.getChangeTime(0);
else
tmax = node.getParent().getHeight();
left.removeChange(leftIdx);
right.removeChange(rightIdx);
mtNode.setNodeType(leftTypeUnder);
double tnew = Randomizer.nextDouble() * (tmax - node.getHeight()) + node.getHeight();
mtNode.insertChange(0, leftType, tnew);
return Math.log(tmax - node.getHeight()) - Math.log((node.getHeight() - tminLeft) * (node.getHeight() - tminRight));
}
use of beast.evolution.tree.MultiTypeNode 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.MultiTypeNode 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);
}
Aggregations