- That depends on who defines which columns are the “sick” ones and which are the “healthy” ones. In the original Excel-File, this information was taken from the color of the cell, but this information is not available in the CSV file. If you want to, you can return to using the Excel file format. You ““only”” have to change the lines
SimpleTableData sickTable = SimpleTableData.create(table, sickColumns);
SimpleTableData healthyTable = SimpleTableData.create(table, healthyColumns);
to something like
SimpleTableData sickTable = createTheTableWithAllSickEntriesMaybeByReading("thisFile.xml");
SimpleTableData healthyTable = createTheTableWithAllHealthyEntriesMaybeByReading("thisFile.xml");
and implement the methods for creating these tables accordingly.
Concerning the other points: Here is an updated main file, but you REALLY should do what is necessary to be able to do things like this on your own! (The problem ist: These things are trivial compared to changing the input from CSV to XML and automatically detect the healthy/sick entries, so I assume that you won’t be able to do this either… -_- )
package fisher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class JCudaFisherTestMain
{
private static Map<String, Integer> valueToIndex;
private static Map<Integer, String> indexToValue;
private static void initMapping()
{
valueToIndex = new LinkedHashMap<String, Integer>();
valueToIndex.put("A/A", 0);
valueToIndex.put("A/C", 1);
valueToIndex.put("A/G", 2);
valueToIndex.put("A/T", 3);
valueToIndex.put("C/A", 4);
valueToIndex.put("C/C", 5);
valueToIndex.put("C/G", 6);
valueToIndex.put("C/T", 7);
valueToIndex.put("G/A", 8);
valueToIndex.put("G/C", 9);
valueToIndex.put("G/G", 10);
valueToIndex.put("G/T", 11);
valueToIndex.put("T/A", 12);
valueToIndex.put("T/C", 13);
valueToIndex.put("T/G", 14);
valueToIndex.put("T/T", 15);
valueToIndex.put("NoCall", 16);
valueToIndex.put("-/-", 17);
valueToIndex.put("-/A", 18);
valueToIndex.put("-/C", 19);
valueToIndex.put("-/G", 20);
valueToIndex.put("-/T", 21);
valueToIndex.put("A/-", 22);
valueToIndex.put("C/-", 23);
valueToIndex.put("G/-", 24);
valueToIndex.put("T/-", 25);
indexToValue = reverse(valueToIndex);
}
public static void main(String[] args) throws Exception
{
initMapping();
SimpleTableData table = SimpleTableData.read("FirstTable.csv");
List<Integer> sickColumns = Arrays.asList(
2, 3, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 25, 27
);
Set<Integer> set = new LinkedHashSet<Integer>();
for (int i=1; i<table.getNumCols(); i++)
{
set.add(i);
}
set.removeAll(sickColumns);
List<Integer> healthyColumns = new ArrayList<Integer>(set);
SimpleTableData sickTable = SimpleTableData.create(table, sickColumns);
SimpleTableData healthyTable = SimpleTableData.create(table, healthyColumns);
int printedRows = table.getNumRows();
System.out.println("Sick table");
System.out.println(sickTable.toString(printedRows));
System.out.println("Healthy table");
System.out.println(healthyTable.toString(printedRows));
int sickCount[] = createCountMatrix(sickTable);
int healthyCount[] = createCountMatrix(healthyTable);
int numRows = table.getNumRows();
int numCols = valueToIndex.size();
int handledRows = numRows;
int handledCols = numCols;
//System.out.println("Start of sick count table");
//System.out.println(toString2D(sickCount, numCols, printedRows));
//System.out.println("Start of healthy count table");
//System.out.println(toString2D(healthyCount, numCols, printedRows));
System.out.println("Sick count table");
printCountTable(sickCount, table);
System.out.println("Healthy count table");
printCountTable(healthyCount, table);
int tasks[] = new int[4];
int numTasks = 0;
for (int r=0; r<handledRows; r++)
{
for (int c0=0; c0<handledCols; c0++)
{
int index0 = c0+r*numCols;
int h0 = healthyCount[index0];
if (h0 != 0)
{
for (int c1=0; c1<handledCols; c1++)
{
int index1 = c1+r*numCols;
int s1 = sickCount[index1];
if (s1 != 0)
{
int h1 = healthyCount[index1];
int s0 = sickCount[index0];
tasks[numTasks*4+0] = h0;
tasks[numTasks*4+1] = h1;
tasks[numTasks*4+2] = s0;
tasks[numTasks*4+3] = s1;
boolean printTasks = false;
//printTasks = true;
if (printTasks)
{
System.out.println("Storing task:");
print(tasks, numTasks, c0, c1);
}
numTasks++;
if (numTasks*4+0 >= tasks.length)
{
tasks = Arrays.copyOf(tasks, tasks.length*2);
}
}
}
}
}
}
long before = 0;
long after = 0;
boolean artificiallyIncreaseSize = false;
//artificiallyIncreaseSize = true;
if (artificiallyIncreaseSize)
{
int n = 100;
int moreTasks[] = new int[numTasks*n*4];
for (int i=0; i<n; i++)
{
System.arraycopy(tasks, 0, moreTasks, i*numTasks*4, numTasks*4);
}
numTasks *= n;
tasks = moreTasks;
}
FisherExactTestCore coreJava = new FisherExactTestCoreJava(1000000);
float resultsJava[] = new float[numTasks];
before = System.nanoTime();
coreJava.computeTwoTailedPs(tasks, numTasks, resultsJava);
after = System.nanoTime();
double javaDurationMS = (after-before)/1e6;
FisherExactTestCore coreCuda = new FisherExactTestCoreJCuda(1000000);
float resultsCuda[] = new float[numTasks];
before = System.nanoTime();
coreCuda.computeTwoTailedPs(tasks, numTasks, resultsCuda);
after = System.nanoTime();
double cudaDurationMS = (after-before)/1e6;
coreCuda.shutdown();
for (int i=0; i<numTasks; i++)
{
int h0 = tasks[i*4+0];
int h1 = tasks[i*4+1];
int s0 = tasks[i*4+2];
int s1 = tasks[i*4+3];
float resultCuda = resultsCuda**;
System.out.printf("For %3d %3d %3d %3d : P-value: %f
", h0, h1, s0, s1, resultCuda);
}
System.out.println("Java Duration "+javaDurationMS+" ms");
System.out.println("CUDA Duration "+cudaDurationMS+" ms");
}
private static void printCountTable(int countTable[], SimpleTableData inputTable)
{
System.out.println("Count table:");
StringBuilder sb = new StringBuilder();
sb.append(String.format("%10s", ""));
for (int c=0; c<indexToValue.size(); c++)
{
sb.append(String.format("%8s", indexToValue.get(c)));
}
sb.append("
");
for (int r=0; r<inputTable.getNumRows(); r++)
{
String s = String.format("%10s", inputTable.getRow(r).get(0));
sb.append(s);
for (int c=0; c<indexToValue.size(); c++)
{
int index = c+r*indexToValue.size();
sb.append(String.format("%8s", countTable[index]));
}
sb.append("
");
}
System.out.println(sb.toString());
}
private static void print(int tasks[], int index, int c0, int c1)
{
int h0 = tasks[index*4+0];
int h1 = tasks[index*4+1];
int s0 = tasks[index*4+2];
int s1 = tasks[index*4+3];
System.out.printf("%8s %3s %3s
", "", "H", "S");
System.out.printf("%8s %3s %3s
", indexToValue.get(c0), String.valueOf(h0), String.valueOf(s0));
System.out.printf("%8s %3s %3s ", indexToValue.get(c1), String.valueOf(h1), String.valueOf(s1));
System.out.printf("
");
System.out.printf("
");
}
private static <K, V> Map<V, K> reverse(Map<K, V> input)
{
Map<V, K> result = new LinkedHashMap<V, K>();
for (Entry<K, V> entry : input.entrySet())
{
result.put(entry.getValue(), entry.getKey());
}
return result;
}
private static int[] createCountMatrix(TableData tableData)
{
int result[] = new int[valueToIndex.size() * tableData.getNumRows()];
for (int r=0; r<tableData.getNumRows(); r++)
{
for (int c=0; c<tableData.getNumCols(); c++)
{
String value = tableData.get(r, c);
Integer index = valueToIndex.get(value);
if (index != null)
{
int arrayIndex = r * valueToIndex.size() + index;
result[arrayIndex]++;
}
}
}
return result;
}
public static String toString2D(int a[], int columns, int maxRows)
{
StringBuilder sb = new StringBuilder();
int row = 0;
for (int i=0; i<a.length; i++)
{
if (i>0 && i % columns == 0)
{
sb.append("
");
row++;
if (maxRows > 0 && row >= maxRows)
{
sb.append("...
");
break;
}
}
sb.append(String.format("%4s ", String.valueOf(a**)));
}
return sb.toString();
}
}