package test.dr.evomodel.substmodel;
import dr.evolution.datatype.Nucleotides;
import dr.oldevomodel.substmodel.FrequencyModel;
import dr.oldevomodel.substmodel.TN93;
import dr.inference.model.Parameter;
import junit.framework.TestCase;
/**
* Test HKY matrix exponentiation
*
* @author Joseph Heled
* Date: 7/11/2007
*/
public class TN93Test extends TestCase {
interface Instance {
double[] getPi();
double getKappa1();
double getKappa2();
double getDistance();
double[] getExpectedResult();
}
/*
* Results obtained by running the following scilab code,
*
* ACGT
*
* k1 = 2 ; k2 = 3; piQ = diag([.25, .25, .25, .25]) ; d = 0.1 ;
* % Q matrix with zeroed diagonal
* XQ = [0 1 k1 1; 1 0 1 k2 ; k1 1 0 1 ; 1 k2 1 0]
*
* xx = XQ * piQ ;
*
* % fill diagonal and normalize by total substitution rate
* q0 = (xx + diag(-sum(xx,2))) / sum(piQ * sum(xx,2)) ;
* expm(q0 * d)
*/
Instance test0 = new Instance() {
public double[] getPi() {
return new double[]{0.25, 0.25, 0.25,0.25};
}
public double getKappa1() {
return 2;
}
public double getKappa2() {
return 3;
}
public double getDistance() {
return 0.1;
}
public double[] getExpectedResult() {
return new double[]{
0.916323466703981 , 0.021263192817492 , 0.041150147661034 , 0.021263192817492 ,
0.021263192817492 , 0.897301022862890 , 0.021263192817493 , 0.060172591502126 ,
0.041150147661034 , 0.021263192817492 , 0.916323466703982 , 0.021263192817492 ,
0.021263192817492 , 0.060172591502126 , 0.021263192817492 , 0.897301022862889 ,
};
}
};
Instance test1 = new Instance() {
public double[] getPi() {
return new double[]{0.1, 0.2, 0.3, 0.4};
}
public double getKappa1() {
return 2;
}
public double getKappa2() {
return 3;
}
public double getDistance() {
return 0.1;
}
public double[] getExpectedResult() {
return new double[]{
0.895550254199242, 0.017687039418335, 0.051388627545752, 0.035374078836670,
0.008843519709168, 0.865344657365451, 0.026530559127503, 0.099281263797879,
0.017129542515251, 0.017687039418335, 0.929809339229744, 0.035374078836670,
0.008843519709168, 0.049640631898940, 0.026530559127503, 0.914985289264390,
};
}
};
Instance test2 = new Instance() {
public double[] getPi() {
return new double[]{0.1, 0.2, 0.3, 0.4};
}
public double getKappa1() {
return 1;
}
public double getKappa2() {
return 3;
}
public double getDistance() {
return 0.1;
}
public double[] getExpectedResult() {
return new double[]{
0.915952014632886, 0.018677330081581, 0.028015995122371, 0.037354660163162,
0.009338665040790, 0.858207194100208, 0.028015995122371, 0.104438145736630,
0.009338665040790, 0.018677330081581, 0.934629344714466, 0.037354660163162,
0.009338665040790, 0.052219072868315, 0.028015995122371, 0.910426266968523,
};
}
};
Instance[] all = {test2, test1, test0};
public void testTN93() {
for( Instance test : all ) {
Parameter kappa1 = new Parameter.Default(1, test.getKappa1());
Parameter kappa2 = new Parameter.Default(1, test.getKappa2());
double[] pi = test.getPi();
Parameter freqs = new Parameter.Default(pi);
FrequencyModel f = new FrequencyModel(Nucleotides.INSTANCE, freqs);
TN93 tn93 = new TN93(kappa1, kappa2, f);
double distance = test.getDistance();
double[] mat = new double[4*4];
tn93.getTransitionProbabilities(distance, mat);
final double[] result = test.getExpectedResult();
for(int k = 0; k < mat.length; ++k) {
assertEquals(mat[k], result[k], 1e-10);
// System.out.print(" " + (mat[k] - result[k]));
}
}
}
}