package statalign.base.mcmc;
import java.util.List;
import java.util.ArrayList;
import statalign.base.Tree;
import statalign.base.Utils;
import statalign.base.Vertex;
import statalign.mcmc.ContinuousPositiveParameterMove;
import statalign.mcmc.McmcModule;
import statalign.mcmc.McmcMove;
import statalign.mcmc.ParameterInterface;
import statalign.mcmc.PriorDistribution;
import statalign.mcmc.ProposalDistribution;
public class AllEdgeMove extends ContinuousPositiveParameterMove {
double multiplier = 1.0;
class AllEdgeInterface implements ParameterInterface {
public double get() {
return 1;
}
public void set(double x) {
multiplier = x;
for (int i=0; i<tree.vertex.length-1; i++) {
tree.vertex[i].edgeLength *= x;
}
}
}
public AllEdgeMove (McmcModule m,
PriorDistribution<Double> pr,
ProposalDistribution<Double> prop, String n) {
super(m,null,pr,prop,n);
param = new AllEdgeInterface();
//minValue = 0.01;
minValue = Utils.MIN_EDGE_LENGTH;
}
@Override
public void copyState(Object externalState) {
if (externalState instanceof Tree) {
if (tree == null) {
tree = (Tree) externalState;
}
}
else {
throw new IllegalArgumentException("AllEdgeMove.move must take an argument of type Tree.");
}
((CoreMcmcModule) owner).getModelExtMan().beforeEdgeLenChange(tree,tree.vertex[0]);
// Should pass the index of a tip Vertex?
super.copyState(externalState);
}
@Override
public void afterMove(Object externalState) {
((CoreMcmcModule) owner).getModelExtMan().afterEdgeLenChange(tree,tree.vertex[0],lastMoveAccepted);
// Should pass the index of a tip Vertex?
}
@Override
public double proposal(Object externalState) {
double logProposalRatio = super.proposal(externalState);
for (int i=0; i<tree.vertex.length-1; i++) {
if (tree.vertex[i].edgeLength < Utils.MIN_EDGE_LENGTH) {
logProposalRatio = Double.NEGATIVE_INFINITY;
}
tree.vertex[i].edgeChangeUpdate();
}
// tree.root.edgeChangeUpdateRecursively();
tree.root.calcFelsenRecursively();
tree.root.calcIndelLogLikeRecursively();
return logProposalRatio;
}
@Override
public double logPriorDensity(Object externalState) {
double logDensity = 0;
for (int i=0; i<tree.vertex.length-1; i++) {
logDensity += prior.logDensityUnnormalised(tree.vertex[i].edgeLength);
}
return logDensity;
}
public void updateLikelihood(Object externalState) {
owner.setLogLike(((CoreMcmcModule) owner).getModelExtMan().logLikeEdgeLenChange(tree, tree.vertex[0]));
// Should pass the index of a tip Vertex?
}
@Override
public void restoreState(Object externalState) {
owner.setLogLike(oldll);
for (int i=0; i<tree.vertex.length-1; i++) {
tree.vertex[i].edgeLength /= multiplier;
tree.vertex[i].edgeChangeUpdate();
}
// tree.root.edgeChangeUpdateRecursively();
// TODO Save the old likelihoods and seq vectors,
// and restore rather than recomputing
tree.root.calcFelsenRecursively();
tree.root.calcIndelLogLikeRecursively();
}
}