package statalign.model.ext.plugins.structalign;
import java.util.ArrayList;
import org.apache.commons.math3.util.MathArrays;
import statalign.base.Utils;
import statalign.base.Vertex;
import statalign.base.Tree;
import statalign.mcmc.McmcMove;
import statalign.model.ext.plugins.StructAlign;
public abstract class RotationOrTranslationMove extends McmcMove {
Tree tree;
protected StructAlign structAlign;
public StructAlignMoveParams moveParams = new StructAlignMoveParams();
double[][] oldaxes = null;
double[] oldangles = null;
double[][] oldxlats = null;
double[][][] oldrots = null;
double oldll;
Vertex subtreeRoot;
AlignmentMove alignmentMove;
int nLeaves;
ArrayList<Integer> subtreeLeaves;
int nStrucInSubtree;
int index;
public void shareSubtreeRoot(AlignmentMove m) {
alignmentMove = m;
System.out.println("Move '"+name+"' now sharing subtree root with move '"+m.name+"'");
}
public Vertex getSharedSubtreeRoot() {
return alignmentMove.getSubtreeRoot();
}
public void copyState(Object externalState) {
if (externalState instanceof Tree) {
tree = (Tree) externalState;
}
else {
throw new IllegalArgumentException("RotationOrTranslationMove.copyState must take an argument of type Tree.");
}
if (Utils.DEBUG) {
System.out.print(inCombination?"In combination\n":"");
System.out.println("Shared root = "+getSharedSubtreeRoot());
}
if (inCombination) subtreeRoot = getSharedSubtreeRoot();
else subtreeRoot = Funcs.sampleVertex(tree);
nLeaves = structAlign.coords.length;
subtreeLeaves = Subtree.getSubtreeLeaves(tree, subtreeRoot, nLeaves);
index = subtreeLeaves.get(Utils.generator.nextInt(subtreeLeaves.size()));
int refInd = 0;
//while (structAlign.axes[refInd]==null) ++refInd;
while (structAlign.coords[refInd]==null) ++refInd;
oldaxes = new double[structAlign.axes.length][structAlign.axes[refInd].length];
oldangles = new double[structAlign.angles.length];
oldxlats = new double[structAlign.xlats.length][structAlign.xlats.length];
oldrots = new double[structAlign.rotCoords.length][structAlign.rotCoords[refInd].length][structAlign.rotCoords[refInd][refInd].length];
nStrucInSubtree = 0;
for(int i = 0; i < subtreeLeaves.size(); i++){
int j = subtreeLeaves.get(i);
//if (structAlign.axes[j] == null) continue;
if (structAlign.coords[j] == null) continue;
nStrucInSubtree++;
oldaxes[j] = MathArrays.copyOf(structAlign.axes[j]);
oldangles[j] = structAlign.angles[j];
oldxlats[j] = MathArrays.copyOf(structAlign.xlats[j]);
oldrots[j] = structAlign.rotCoords[j];
}
oldll = owner.getLogLike();
}
public double proposal(Object externalState) {
// if (nStrucInSubtree==0) return Double.NEGATIVE_INFINITY;
// else return 0;
//System.out.println(name+" "+proposalWidthControlVariable);
return 0;
}
public double logPriorDensity(Object externalState) {
return 0; // Uniform prior
}
public void updateLikelihood(Object externalState) {
for(int i = 0; i < subtreeLeaves.size(); i++){
int j = subtreeLeaves.get(i);
if (structAlign.coords[j] == null) continue;
structAlign.rotCoords[j] = null; // so that calcRotation creates new array
structAlign.calcRotation(j);
}
owner.setLogLike( structAlign.calcAllColumnContrib() );
}
public void restoreState(Object externalState) {
for(int i = 0; i < subtreeLeaves.size(); i++){
int j = subtreeLeaves.get(i);
structAlign.axes[j] = oldaxes[j];
structAlign.angles[j] = oldangles[j];
structAlign.xlats[j] = oldxlats[j];
structAlign.rotCoords[j] = oldrots[j];
}
owner.setLogLike(oldll);
}
public void afterMove(Object externalState) {
}
}