package templates;
import gui.InteractiveTableModel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import readers.LogFileReader;
import utils.Holder;
import utils.Utils;
import utils.Utils.PoissonPriorEnum;
/**
* Pass by reference
*
* */
public class BayesFactorTest {
private Holder meanPoissonPrior;
private Holder poissonPriorOffset;
private InteractiveTableModel table;
private PoissonPriorEnum meanPoissonPriorSwitcher;
private PoissonPriorEnum poissonPriorOffsetSwitcher;
private LogFileReader indicators;
private ArrayList<String> combin;
private ArrayList<Double> bayesFactors;
private ArrayList<Double> posteriorProbabilities;
public BayesFactorTest(InteractiveTableModel table, //
PoissonPriorEnum meanPoissonPriorSwitcher, //
Holder meanPoissonPriorHolder, //
PoissonPriorEnum poissonPriorOffsetSwitcher, //
Holder poissonPriorOffsetHolder, //
LogFileReader indicators, //
ArrayList<String> combin, //
ArrayList<Double> bayesFactors, //
ArrayList<Double> posteriorProbabilities //
) {
this.table = table;
this.meanPoissonPriorSwitcher = meanPoissonPriorSwitcher;
this.meanPoissonPrior = meanPoissonPriorHolder;
this.poissonPriorOffsetSwitcher = poissonPriorOffsetSwitcher;
this.poissonPriorOffset = poissonPriorOffsetHolder;
this.indicators = indicators;
this.combin = combin;
this.bayesFactors = bayesFactors;
this.posteriorProbabilities = posteriorProbabilities;
}
public void ComputeBFTest() {
int n = table.getRowCount();
switch (meanPoissonPriorSwitcher) {
case DEFAULT:
meanPoissonPrior.value = Math.log(2);
break;
case USER:
break;
}
switch (poissonPriorOffsetSwitcher) {
case DEFAULT:
poissonPriorOffset.value = (double) (n - 1);
break;
case USER:
break;
}
boolean symmetrical = false;
if (indicators.ncol == n * (n - 1)) {
symmetrical = false;
} else if (indicators.ncol == (n * (n - 1)) / 2) {
symmetrical = true;
} else {
throw new RuntimeException(
"the number of rate indicators does not match the number of locations!");
}
String[] locations = table.getColumn(0);
for (int row = 0; row < n - 1; row++) {
String[] subset = Utils.subset(locations, row, n - row);
for (int i = 1; i < subset.length; i++) {
combin.add(locations[row] + ":" + subset[i]);
}
}
if (symmetrical == false) {
List<String> combinReverse = new ArrayList<String>();
for (int i = 0; i < combin.size(); i++) {
String state = combin.get(i).split(":")[1];
String parentState = combin.get(i).split(":")[0];
combinReverse.add(state + ":" + parentState);
}
combin.addAll(combinReverse);
}
double qk = Double.NaN;
if (symmetrical) {
qk = (meanPoissonPrior.value + poissonPriorOffset.value)
/ ((n * (n - 1)) / 2);
} else {
qk = (meanPoissonPrior.value + poissonPriorOffset.value)
/ ((n * (n - 1)) / 1);
}
double[] pk = Utils.colMeans(indicators.indicators);
double denominator = qk / (1 - qk);
for (int row = 0; row < pk.length; row++) {
double bf = (pk[row] / (1 - pk[row])) / denominator;
if (bf == Double.POSITIVE_INFINITY) {
bf = ((pk[row] - (double) (1.0 / indicators.nrow)) / (1 - (pk[row] - (double) (1.0 / indicators.nrow))))
/ denominator;
System.out.println("Correcting for infinite bf: " + bf);
}// END: infinite BF check
bayesFactors.add(bf);
posteriorProbabilities.add(pk[row]);
}// END: row loop
}// END: ComputeBFTest
/**
* @return array with sort order indices to be used to print bayesFactors
* and combin lists in descending order
* */
public Integer[] getSortOrder() {
Integer[] sortOrder = new Integer[bayesFactors.size()];
for (int i = 0; i < sortOrder.length; i++) {
sortOrder[i] = i;
}
Arrays.sort(sortOrder, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
return (bayesFactors.get(b) > bayesFactors.get(a)) ? 1 : -1;
}
});
return sortOrder;
}// END: getSortOrder
}// END: BayesFactorTest